NEST  2.6.0,not_revisioned_source_dir@0
type_traits.h
Go to the documentation of this file.
1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
29 
30 // ----
31 //
32 // This code is compiled directly on many platforms, including client
33 // platforms like Windows, Mac, and embedded systems. Before making
34 // any changes here, make sure that you're not breaking any platforms.
35 //
36 // Define a small subset of tr1 type traits. The traits we define are:
37 // is_integral
38 // is_floating_point
39 // is_pointer
40 // is_enum
41 // is_reference
42 // is_pod
43 // has_trivial_constructor
44 // has_trivial_copy
45 // has_trivial_assign
46 // has_trivial_destructor
47 // remove_const
48 // remove_volatile
49 // remove_cv
50 // remove_reference
51 // add_reference
52 // remove_pointer
53 // is_same
54 // is_convertible
55 // We can add more type traits as required.
56 
57 #ifndef BASE_TYPE_TRAITS_H_
58 #define BASE_TYPE_TRAITS_H_
59 
60 #include <sparseconfig.h>
61 #include <utility> // For pair
62 
63 #include <template_util.h> // For true_type and false_type
64 
65 _START_GOOGLE_NAMESPACE_
66 
67 template <class T> struct is_integral;
68 template <class T> struct is_floating_point;
69 template <class T> struct is_pointer;
70 // MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
71 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
72 // is_enum uses is_convertible, which is not available on MSVC.
73 template <class T> struct is_enum;
74 #endif
75 template <class T> struct is_reference;
76 template <class T> struct is_pod;
77 template <class T> struct has_trivial_constructor;
78 template <class T> struct has_trivial_copy;
79 template <class T> struct has_trivial_assign;
80 template <class T> struct has_trivial_destructor;
81 template <class T> struct remove_const;
82 template <class T> struct remove_volatile;
83 template <class T> struct remove_cv;
84 template <class T> struct remove_reference;
85 template <class T> struct add_reference;
86 template <class T> struct remove_pointer;
87 template <class T, class U> struct is_same;
88 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
89 template <class From, class To> struct is_convertible;
90 #endif
91 
92 // is_integral is false except for the built-in integer types. A
93 // cv-qualified type is integral if and only if the underlying type is.
94 template <class T> struct is_integral : false_type { };
95 template<> struct is_integral<bool> : true_type { };
96 template<> struct is_integral<char> : true_type { };
97 template<> struct is_integral<unsigned char> : true_type { };
98 template<> struct is_integral<signed char> : true_type { };
99 #if defined(_MSC_VER)
100 // wchar_t is not by default a distinct type from unsigned short in
101 // Microsoft C.
102 // See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
103 template<> struct is_integral<__wchar_t> : true_type { };
104 #else
105 template<> struct is_integral<wchar_t> : true_type { };
106 #endif
107 template<> struct is_integral<short> : true_type { };
108 template<> struct is_integral<unsigned short> : true_type { };
109 template<> struct is_integral<int> : true_type { };
110 template<> struct is_integral<unsigned int> : true_type { };
111 template<> struct is_integral<long> : true_type { };
112 template<> struct is_integral<unsigned long> : true_type { };
113 #ifdef HAVE_LONG_LONG
114 template<> struct is_integral<long long> : true_type { };
115 template<> struct is_integral<unsigned long long> : true_type { };
116 #endif
117 template <class T> struct is_integral<const T> : is_integral<T> { };
118 template <class T> struct is_integral<volatile T> : is_integral<T> { };
119 template <class T> struct is_integral<const volatile T> : is_integral<T> { };
120 
121 // is_floating_point is false except for the built-in floating-point types.
122 // A cv-qualified type is integral if and only if the underlying type is.
123 template <class T> struct is_floating_point : false_type { };
124 template<> struct is_floating_point<float> : true_type { };
125 template<> struct is_floating_point<double> : true_type { };
126 template<> struct is_floating_point<long double> : true_type { };
127 template <class T> struct is_floating_point<const T>
128  : is_floating_point<T> { };
129 template <class T> struct is_floating_point<volatile T>
130  : is_floating_point<T> { };
131 template <class T> struct is_floating_point<const volatile T>
132  : is_floating_point<T> { };
133 
134 // is_pointer is false except for pointer types. A cv-qualified type (e.g.
135 // "int* const", as opposed to "int const*") is cv-qualified if and only if
136 // the underlying type is.
137 template <class T> struct is_pointer : false_type { };
138 template <class T> struct is_pointer<T*> : true_type { };
139 template <class T> struct is_pointer<const T> : is_pointer<T> { };
140 template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
141 template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
142 
143 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
144 
145 namespace internal {
146 
147 template <class T> struct is_class_or_union {
148  template <class U> static small_ tester(void (U::*)());
149  template <class U> static big_ tester(...);
150  static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
151 };
152 
153 // is_convertible chokes if the first argument is an array. That's why
154 // we use add_reference here.
155 template <bool NotUnum, class T> struct is_enum_impl
156  : is_convertible<typename add_reference<T>::type, int> { };
157 
158 template <class T> struct is_enum_impl<true, T> : false_type { };
159 
160 } // namespace internal
161 
162 // Specified by TR1 [4.5.1] primary type categories.
163 
164 // Implementation note:
165 //
166 // Each type is either void, integral, floating point, array, pointer,
167 // reference, member object pointer, member function pointer, enum,
168 // union or class. Out of these, only integral, floating point, reference,
169 // class and enum types are potentially convertible to int. Therefore,
170 // if a type is not a reference, integral, floating point or class and
171 // is convertible to int, it's a enum. Adding cv-qualification to a type
172 // does not change whether it's an enum.
173 //
174 // Is-convertible-to-int check is done only if all other checks pass,
175 // because it can't be used with some types (e.g. void or classes with
176 // inaccessible conversion operators).
177 template <class T> struct is_enum
179  is_same<T, void>::value ||
180  is_integral<T>::value ||
181  is_floating_point<T>::value ||
182  is_reference<T>::value ||
183  internal::is_class_or_union<T>::value,
184  T> { };
185 
186 template <class T> struct is_enum<const T> : is_enum<T> { };
187 template <class T> struct is_enum<volatile T> : is_enum<T> { };
188 template <class T> struct is_enum<const volatile T> : is_enum<T> { };
189 
190 #endif
191 
192 // is_reference is false except for reference types.
193 template<typename T> struct is_reference : false_type {};
194 template<typename T> struct is_reference<T&> : true_type {};
195 
196 
197 // We can't get is_pod right without compiler help, so fail conservatively.
198 // We will assume it's false except for arithmetic types, enumerations,
199 // pointers and cv-qualified versions thereof. Note that std::pair<T,U>
200 // is not a POD even if T and U are PODs.
201 template <class T> struct is_pod
202  : integral_constant<bool, (is_integral<T>::value ||
203  is_floating_point<T>::value ||
204 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
205  // is_enum is not available on MSVC.
206  is_enum<T>::value ||
207 #endif
208  is_pointer<T>::value)> { };
209 template <class T> struct is_pod<const T> : is_pod<T> { };
210 template <class T> struct is_pod<volatile T> : is_pod<T> { };
211 template <class T> struct is_pod<const volatile T> : is_pod<T> { };
212 
213 
214 // We can't get has_trivial_constructor right without compiler help, so
215 // fail conservatively. We will assume it's false except for: (1) types
216 // for which is_pod is true. (2) std::pair of types with trivial
217 // constructors. (3) array of a type with a trivial constructor.
218 // (4) const versions thereof.
219 template <class T> struct has_trivial_constructor : is_pod<T> { };
220 template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
221  : integral_constant<bool,
222  (has_trivial_constructor<T>::value &&
223  has_trivial_constructor<U>::value)> { };
224 template <class A, int N> struct has_trivial_constructor<A[N]>
225  : has_trivial_constructor<A> { };
226 template <class T> struct has_trivial_constructor<const T>
227  : has_trivial_constructor<T> { };
228 
229 // We can't get has_trivial_copy right without compiler help, so fail
230 // conservatively. We will assume it's false except for: (1) types
231 // for which is_pod is true. (2) std::pair of types with trivial copy
232 // constructors. (3) array of a type with a trivial copy constructor.
233 // (4) const versions thereof.
234 template <class T> struct has_trivial_copy : is_pod<T> { };
235 template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
236  : integral_constant<bool,
237  (has_trivial_copy<T>::value &&
238  has_trivial_copy<U>::value)> { };
239 template <class A, int N> struct has_trivial_copy<A[N]>
240  : has_trivial_copy<A> { };
241 template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
242 
243 // We can't get has_trivial_assign right without compiler help, so fail
244 // conservatively. We will assume it's false except for: (1) types
245 // for which is_pod is true. (2) std::pair of types with trivial copy
246 // constructors. (3) array of a type with a trivial assign constructor.
247 template <class T> struct has_trivial_assign : is_pod<T> { };
248 template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
249  : integral_constant<bool,
250  (has_trivial_assign<T>::value &&
251  has_trivial_assign<U>::value)> { };
252 template <class A, int N> struct has_trivial_assign<A[N]>
253  : has_trivial_assign<A> { };
254 
255 // We can't get has_trivial_destructor right without compiler help, so
256 // fail conservatively. We will assume it's false except for: (1) types
257 // for which is_pod is true. (2) std::pair of types with trivial
258 // destructors. (3) array of a type with a trivial destructor.
259 // (4) const versions thereof.
260 template <class T> struct has_trivial_destructor : is_pod<T> { };
261 template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
262  : integral_constant<bool,
263  (has_trivial_destructor<T>::value &&
264  has_trivial_destructor<U>::value)> { };
265 template <class A, int N> struct has_trivial_destructor<A[N]>
266  : has_trivial_destructor<A> { };
267 template <class T> struct has_trivial_destructor<const T>
268  : has_trivial_destructor<T> { };
269 
270 // Specified by TR1 [4.7.1]
271 template<typename T> struct remove_const { typedef T type; };
272 template<typename T> struct remove_const<T const> { typedef T type; };
273 template<typename T> struct remove_volatile { typedef T type; };
274 template<typename T> struct remove_volatile<T volatile> { typedef T type; };
275 template<typename T> struct remove_cv {
276  typedef typename remove_const<typename remove_volatile<T>::type>::type type;
277 };
278 
279 
280 // Specified by TR1 [4.7.2] Reference modifications.
281 template<typename T> struct remove_reference { typedef T type; };
282 template<typename T> struct remove_reference<T&> { typedef T type; };
283 
284 template <typename T> struct add_reference { typedef T& type; };
285 template <typename T> struct add_reference<T&> { typedef T& type; };
286 
287 // Specified by TR1 [4.7.4] Pointer modifications.
288 template<typename T> struct remove_pointer { typedef T type; };
289 template<typename T> struct remove_pointer<T*> { typedef T type; };
290 template<typename T> struct remove_pointer<T* const> { typedef T type; };
291 template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
292 template<typename T> struct remove_pointer<T* const volatile> {
293  typedef T type; };
294 
295 // Specified by TR1 [4.6] Relationships between types
296 template<typename T, typename U> struct is_same : public false_type { };
297 template<typename T> struct is_same<T, T> : public true_type { };
298 
299 // Specified by TR1 [4.6] Relationships between types
300 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
301 namespace internal {
302 
303 // This class is an implementation detail for is_convertible, and you
304 // don't need to know how it works to use is_convertible. For those
305 // who care: we declare two different functions, one whose argument is
306 // of type To and one with a variadic argument list. We give them
307 // return types of different size, so we can use sizeof to trick the
308 // compiler into telling us which function it would have chosen if we
309 // had called it with an argument of type From. See Alexandrescu's
310 // _Modern C++ Design_ for more details on this sort of trick.
311 
312 template <typename From, typename To>
313 struct ConvertHelper {
314  static small_ Test(To);
315  static big_ Test(...);
316  static From Create();
317 };
318 } // namespace internal
319 
320 // Inherits from true_type if From is convertible to To, false_type otherwise.
321 template <typename From, typename To>
322 struct is_convertible
323  : integral_constant<bool,
324  sizeof(internal::ConvertHelper<From, To>::Test(
325  internal::ConvertHelper<From, To>::Create()))
326  == sizeof(small_)> {
327 };
328 #endif
329 
330 _END_GOOGLE_NAMESPACE_
331 
332 // Right now these macros are no-ops, and mostly just document the fact
333 // these types are PODs, for human use. They may be made more contentful
334 // later. The typedef is just to make it legal to put a semicolon after
335 // these macros.
336 #define DECLARE_POD(TypeName) typedef int Dummy_Type_For_DECLARE_POD
337 #define DECLARE_NESTED_POD(TypeName) DECLARE_POD(TypeName)
338 #define PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(TemplateName) \
339  typedef int Dummy_Type_For_PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT
340 #define ENFORCE_POD(TypeName) typedef int Dummy_Type_For_ENFORCE_POD
341 
342 #endif // BASE_TYPE_TRAITS_H_
Definition: template_util.h:75
Definition: type_traits.h:155
_START_GOOGLE_NAMESPACE_ typedef char small_
Definition: template_util.h:57
Definition: type_traits.h:68
Definition: type_traits.h:80
Definition: type_traits.h:73
Definition: type_traits.h:86
Definition: type_traits.h:89
Definition: type_traits.h:83
Definition: type_traits.h:76
Definition: type_traits.h:82
Definition: type_traits.h:81
Definition: type_traits.h:85
static const bool value
Definition: type_traits.h:150
Definition: type_traits.h:79
Definition: type_traits.h:77
static small_ tester(void(U::*)())
Definition: type_traits.h:67
Definition: type_traits.h:78
Definition: type_traits.h:87
Definition: type_traits.h:147
Definition: type_traits.h:69
Definition: template_util.h:59
Definition: type_traits.h:84
Definition: type_traits.h:75