OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <limits.h> // So we can set the bounds of our types | 8 #include <limits.h> // So we can set the bounds of our types |
9 #include <stddef.h> // For size_t | 9 #include <stddef.h> // For size_t |
10 #include <string.h> // for memcpy | 10 #include <string.h> // for memcpy |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 // that wants to prevent anyone from instantiating it. This is | 91 // that wants to prevent anyone from instantiating it. This is |
92 // especially useful for classes containing only static methods. | 92 // especially useful for classes containing only static methods. |
93 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ | 93 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ |
94 TypeName(); \ | 94 TypeName(); \ |
95 DISALLOW_COPY_AND_ASSIGN(TypeName) | 95 DISALLOW_COPY_AND_ASSIGN(TypeName) |
96 | 96 |
97 // The arraysize(arr) macro returns the # of elements in an array arr. | 97 // The arraysize(arr) macro returns the # of elements in an array arr. |
98 // The expression is a compile-time constant, and therefore can be | 98 // The expression is a compile-time constant, and therefore can be |
99 // used in defining new arrays, for example. If you use arraysize on | 99 // used in defining new arrays, for example. If you use arraysize on |
100 // a pointer by mistake, you will get a compile-time error. | 100 // a pointer by mistake, you will get a compile-time error. |
101 // | |
102 // One caveat is that arraysize() doesn't accept any array of an | |
103 // anonymous type or a type defined inside a function. In these rare | |
104 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is | |
105 // due to a limitation in C++'s template system. The limitation might | |
106 // eventually be removed, but it hasn't happened yet. | |
107 | 101 |
108 // This template function declaration is used in defining arraysize. | 102 // This template function declaration is used in defining arraysize. |
109 // Note that the function doesn't need an implementation, as we only | 103 // Note that the function doesn't need an implementation, as we only |
110 // use its type. | 104 // use its type. |
111 template <typename T, size_t N> | 105 template <typename T, size_t N> |
112 char (&ArraySizeHelper(T (&array)[N]))[N]; | 106 char (&ArraySizeHelper(T (&array)[N]))[N]; |
113 | 107 |
114 // That gcc wants both of these prototypes seems mysterious. VC, for | 108 // That gcc wants both of these prototypes seems mysterious. VC, for |
115 // its part, can't decide which to use (another mystery). Matching of | 109 // its part, can't decide which to use (another mystery). Matching of |
116 // template overloads: the final frontier. | 110 // template overloads: the final frontier. |
117 #ifndef _MSC_VER | 111 #ifndef _MSC_VER |
118 template <typename T, size_t N> | 112 template <typename T, size_t N> |
119 char (&ArraySizeHelper(const T (&array)[N]))[N]; | 113 char (&ArraySizeHelper(const T (&array)[N]))[N]; |
120 #endif | 114 #endif |
121 | 115 |
122 #define arraysize(array) (sizeof(ArraySizeHelper(array))) | 116 #define arraysize(array) (sizeof(ArraySizeHelper(array))) |
123 | 117 |
124 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, | |
125 // but can be used on anonymous types or types defined inside | |
126 // functions. It's less safe than arraysize as it accepts some | |
127 // (although not all) pointers. Therefore, you should use arraysize | |
128 // whenever possible. | |
129 // | |
130 // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type | |
131 // size_t. | |
132 // | |
133 // ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error | |
134 // | |
135 // "warning: division by zero in ..." | |
136 // | |
137 // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. | |
138 // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. | |
139 // | |
140 // The following comments are on the implementation details, and can | |
141 // be ignored by the users. | |
142 // | |
143 // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in | |
144 // the array) and sizeof(*(arr)) (the # of bytes in one array | |
145 // element). If the former is divisible by the latter, perhaps arr is | |
146 // indeed an array, in which case the division result is the # of | |
147 // elements in the array. Otherwise, arr cannot possibly be an array, | |
148 // and we generate a compiler error to prevent the code from | |
149 // compiling. | |
150 // | |
151 // Since the size of bool is implementation-defined, we need to cast | |
152 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final | |
153 // result has type size_t. | |
154 // | |
155 // This macro is not perfect as it wrongfully accepts certain | |
156 // pointers, namely where the pointer size is divisible by the pointee | |
157 // size. Since all our code has to go through a 32-bit compiler, | |
158 // where a pointer is 4 bytes, this means all pointers to a type whose | |
159 // size is 3 or greater than 4 will be (righteously) rejected. | |
160 | |
161 #define ARRAYSIZE_UNSAFE(a) \ | |
162 ((sizeof(a) / sizeof(*(a))) / \ | |
163 static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) | |
164 | |
165 | 118 |
166 // Use implicit_cast as a safe version of static_cast or const_cast | 119 // Use implicit_cast as a safe version of static_cast or const_cast |
167 // for upcasting in the type hierarchy (i.e. casting a pointer to Foo | 120 // for upcasting in the type hierarchy (i.e. casting a pointer to Foo |
168 // to a pointer to SuperclassOfFoo or casting a pointer to Foo to | 121 // to a pointer to SuperclassOfFoo or casting a pointer to Foo to |
169 // a const pointer to Foo). | 122 // a const pointer to Foo). |
170 // When you use implicit_cast, the compiler checks that the cast is safe. | 123 // When you use implicit_cast, the compiler checks that the cast is safe. |
171 // Such explicit implicit_casts are necessary in surprisingly many | 124 // Such explicit implicit_casts are necessary in surprisingly many |
172 // situations where C++ demands an exact type match instead of an | 125 // situations where C++ demands an exact type match instead of an |
173 // argument type convertable to a target type. | 126 // argument type convertable to a target type. |
174 // | 127 // |
175 // The From type can be inferred, so the preferred syntax for using | 128 // The From type can be inferred, so the preferred syntax for using |
176 // implicit_cast is the same as for static_cast etc.: | 129 // implicit_cast is the same as for static_cast etc.: |
177 // | 130 // |
178 // implicit_cast<ToType>(expr) | 131 // implicit_cast<ToType>(expr) |
179 // | 132 // |
180 // implicit_cast would have been part of the C++ standard library, | 133 // implicit_cast would have been part of the C++ standard library, |
181 // but the proposal was submitted too late. It will probably make | 134 // but the proposal was submitted too late. It will probably make |
182 // its way into the language in the future. | 135 // its way into the language in the future. |
183 template<typename To, typename From> | 136 template<typename To, typename From> |
184 inline To implicit_cast(From const &f) { | 137 inline To implicit_cast(From const &f) { |
185 return f; | 138 return f; |
186 } | 139 } |
187 | 140 |
188 // The COMPILE_ASSERT macro can be used to verify that a compile time | 141 // The COMPILE_ASSERT macro can be used to verify that a compile time |
189 // expression is true. For example, you could use it to verify the | 142 // expression is true. For example, you could use it to verify the |
190 // size of a static array: | 143 // size of a static array: |
191 // | 144 // |
192 // COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES, | 145 // COMPILE_ASSERT(arraysize(content_type_names) == CONTENT_NUM_TYPES, |
193 // content_type_names_incorrect_size); | 146 // content_type_names_incorrect_size); |
194 // | 147 // |
195 // or to make sure a struct is smaller than a certain size: | 148 // or to make sure a struct is smaller than a certain size: |
196 // | 149 // |
197 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); | 150 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); |
198 // | 151 // |
199 // The second argument to the macro is the name of the variable. If | 152 // The second argument to the macro is the name of the variable. If |
200 // the expression is false, most compilers will issue a warning/error | 153 // the expression is false, most compilers will issue a warning/error |
201 // containing the name of the variable. | 154 // containing the name of the variable. |
202 | 155 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 // If target architecture does not support unaligned loads and stores, | 310 // If target architecture does not support unaligned loads and stores, |
358 // use memcpy version of UNALIGNED_LOAD32. | 311 // use memcpy version of UNALIGNED_LOAD32. |
359 inline uint32 UnalignedLoad32(const void* p) { | 312 inline uint32 UnalignedLoad32(const void* p) { |
360 uint32 t; | 313 uint32 t; |
361 memcpy(&t, reinterpret_cast<const uint8*>(p), sizeof(t)); | 314 memcpy(&t, reinterpret_cast<const uint8*>(p), sizeof(t)); |
362 return t; | 315 return t; |
363 } | 316 } |
364 | 317 |
365 #endif | 318 #endif |
366 #endif // BASE_BASICTYPES_H_ | 319 #endif // BASE_BASICTYPES_H_ |
OLD | NEW |