OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium 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 BASE_BASICTYPES_H_ | 5 #ifndef BASE_BASICTYPES_H_ |
6 #define BASE_BASICTYPES_H_ | 6 #define BASE_BASICTYPES_H_ |
7 | 7 |
8 #include <assert.h> // for use with down_cast<> | 8 #include <assert.h> // for use with down_cast<> |
9 #include <limits.h> // So we can set the bounds of our types | 9 #include <limits.h> // So we can set the bounds of our types |
10 #include <stddef.h> // For size_t | 10 #include <stddef.h> // For size_t |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 TypeName(); \ | 95 TypeName(); \ |
96 DISALLOW_COPY_AND_ASSIGN(TypeName) | 96 DISALLOW_COPY_AND_ASSIGN(TypeName) |
97 | 97 |
98 // The arraysize(arr) macro returns the # of elements in an array arr. | 98 // The arraysize(arr) macro returns the # of elements in an array arr. |
99 // The expression is a compile-time constant, and therefore can be | 99 // The expression is a compile-time constant, and therefore can be |
100 // used in defining new arrays, for example. If you use arraysize on | 100 // used in defining new arrays, for example. If you use arraysize on |
101 // a pointer by mistake, you will get a compile-time error. | 101 // a pointer by mistake, you will get a compile-time error. |
102 // | 102 // |
103 // One caveat is that arraysize() doesn't accept any array of an | 103 // One caveat is that arraysize() doesn't accept any array of an |
104 // anonymous type or a type defined inside a function. In these rare | 104 // anonymous type or a type defined inside a function. In these rare |
105 // cases, you have to use the unsafe ARRAYSIZE() macro below. This is | 105 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is |
106 // due to a limitation in C++'s template system. The limitation might | 106 // due to a limitation in C++'s template system. The limitation might |
107 // eventually be removed, but it hasn't happened yet. | 107 // eventually be removed, but it hasn't happened yet. |
108 | 108 |
109 // This template function declaration is used in defining arraysize. | 109 // This template function declaration is used in defining arraysize. |
110 // Note that the function doesn't need an implementation, as we only | 110 // Note that the function doesn't need an implementation, as we only |
111 // use its type. | 111 // use its type. |
112 template <typename T, size_t N> | 112 template <typename T, size_t N> |
113 char (&ArraySizeHelper(T (&array)[N]))[N]; | 113 char (&ArraySizeHelper(T (&array)[N]))[N]; |
114 | 114 |
115 // That gcc wants both of these prototypes seems mysterious. VC, for | 115 // That gcc wants both of these prototypes seems mysterious. VC, for |
116 // its part, can't decide which to use (another mystery). Matching of | 116 // its part, can't decide which to use (another mystery). Matching of |
117 // template overloads: the final frontier. | 117 // template overloads: the final frontier. |
118 #ifndef _MSC_VER | 118 #ifndef _MSC_VER |
119 template <typename T, size_t N> | 119 template <typename T, size_t N> |
120 char (&ArraySizeHelper(const T (&array)[N]))[N]; | 120 char (&ArraySizeHelper(const T (&array)[N]))[N]; |
121 #endif | 121 #endif |
122 | 122 |
123 #define arraysize(array) (sizeof(ArraySizeHelper(array))) | 123 #define arraysize(array) (sizeof(ArraySizeHelper(array))) |
124 | 124 |
125 // ARRAYSIZE performs essentially the same calculation as arraysize, | 125 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, |
126 // but can be used on anonymous types or types defined inside | 126 // but can be used on anonymous types or types defined inside |
127 // functions. It's less safe than arraysize as it accepts some | 127 // functions. It's less safe than arraysize as it accepts some |
128 // (although not all) pointers. Therefore, you should use arraysize | 128 // (although not all) pointers. Therefore, you should use arraysize |
129 // whenever possible. | 129 // whenever possible. |
130 // | 130 // |
131 // The expression ARRAYSIZE(a) is a compile-time constant of type | 131 // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type |
132 // size_t. | 132 // size_t. |
133 // | 133 // |
134 // ARRAYSIZE catches a few type errors. If you see a compiler error | 134 // ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error |
135 // | 135 // |
136 // "warning: division by zero in ..." | 136 // "warning: division by zero in ..." |
137 // | 137 // |
138 // when using ARRAYSIZE, you are (wrongfully) giving it a pointer. | 138 // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. |
139 // You should only use ARRAYSIZE on statically allocated arrays. | 139 // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. |
140 // | 140 // |
141 // The following comments are on the implementation details, and can | 141 // The following comments are on the implementation details, and can |
142 // be ignored by the users. | 142 // be ignored by the users. |
143 // | 143 // |
144 // ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in | 144 // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in |
145 // the array) and sizeof(*(arr)) (the # of bytes in one array | 145 // the array) and sizeof(*(arr)) (the # of bytes in one array |
146 // element). If the former is divisible by the latter, perhaps arr is | 146 // element). If the former is divisible by the latter, perhaps arr is |
147 // indeed an array, in which case the division result is the # of | 147 // indeed an array, in which case the division result is the # of |
148 // elements in the array. Otherwise, arr cannot possibly be an array, | 148 // elements in the array. Otherwise, arr cannot possibly be an array, |
149 // and we generate a compiler error to prevent the code from | 149 // and we generate a compiler error to prevent the code from |
150 // compiling. | 150 // compiling. |
151 // | 151 // |
152 // Since the size of bool is implementation-defined, we need to cast | 152 // Since the size of bool is implementation-defined, we need to cast |
153 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final | 153 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final |
154 // result has type size_t. | 154 // result has type size_t. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 } | 216 } |
217 | 217 |
218 assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only! | 218 assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only! |
219 return static_cast<To>(f); | 219 return static_cast<To>(f); |
220 } | 220 } |
221 | 221 |
222 // The COMPILE_ASSERT macro can be used to verify that a compile time | 222 // The COMPILE_ASSERT macro can be used to verify that a compile time |
223 // expression is true. For example, you could use it to verify the | 223 // expression is true. For example, you could use it to verify the |
224 // size of a static array: | 224 // size of a static array: |
225 // | 225 // |
226 // COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, | 226 // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, |
227 // content_type_names_incorrect_size); | 227 // content_type_names_incorrect_size); |
228 // | 228 // |
229 // or to make sure a struct is smaller than a certain size: | 229 // or to make sure a struct is smaller than a certain size: |
230 // | 230 // |
231 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); | 231 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); |
232 // | 232 // |
233 // The second argument to the macro is the name of the variable. If | 233 // The second argument to the macro is the name of the variable. If |
234 // the expression is false, most compilers will issue a warning/error | 234 // the expression is false, most compilers will issue a warning/error |
235 // containing the name of the variable. | 235 // containing the name of the variable. |
236 | 236 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 // explicit MyClass(base::LinkerInitialized x) {} | 388 // explicit MyClass(base::LinkerInitialized x) {} |
389 // and invoked as | 389 // and invoked as |
390 // static MyClass my_variable_name(base::LINKER_INITIALIZED); | 390 // static MyClass my_variable_name(base::LINKER_INITIALIZED); |
391 namespace base { | 391 namespace base { |
392 enum LinkerInitialized { LINKER_INITIALIZED }; | 392 enum LinkerInitialized { LINKER_INITIALIZED }; |
393 } // base | 393 } // base |
394 | 394 |
395 | 395 |
396 #endif // BASE_BASICTYPES_H_ | 396 #endif // BASE_BASICTYPES_H_ |
397 | 397 |
OLD | NEW |