TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 // Author: Matt Austern
32 //
33 // This code is compiled directly on many platforms, including client
34 // platforms like Windows, Mac, and embedded systems. Before making
35 // any changes here, make sure that you're not breaking any platforms.
36 //
37 // Define a small subset of tr1 type traits. The traits we define are:
38 // is_integral
39 // is_floating_point
40 // is_pointer
41 // is_enum
42 // is_reference
43 // is_pod
44 // has_trivial_constructor
45 // has_trivial_copy
46 // has_trivial_assign
47 // has_trivial_destructor
48 // remove_const
49 // remove_volatile
50 // remove_cv
51 // remove_reference
52 // add_reference
53 // remove_pointer
54 // is_same
55 // is_convertible
56 // We can add more type traits as required.
57 
58 #ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
59 #define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
60 
61 #include <utility> // For pair
62 
63 #include <google/protobuf/stubs/template_util.h> // For true_type and false_type
64 
65 namespace google {
66 namespace protobuf {
67 namespace internal {
68 
69 template <class T> struct is_integral;
70 template <class T> struct is_floating_point;
71 template <class T> struct is_pointer;
72 // MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
73 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
74 // is_enum uses is_convertible, which is not available on MSVC.
75 template <class T> struct is_enum;
76 #endif
77 template <class T> struct is_reference;
78 template <class T> struct is_pod;
79 template <class T> struct has_trivial_constructor;
80 template <class T> struct has_trivial_copy;
81 template <class T> struct has_trivial_assign;
82 template <class T> struct has_trivial_destructor;
83 template <class T> struct remove_const;
84 template <class T> struct remove_volatile;
85 template <class T> struct remove_cv;
86 template <class T> struct remove_reference;
87 template <class T> struct add_reference;
88 template <class T> struct remove_pointer;
89 template <class T, class U> struct is_same;
90 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
91 template <class From, class To> struct is_convertible;
92 #endif
93 
94 // is_integral is false except for the built-in integer types. A
95 // cv-qualified type is integral if and only if the underlying type is.
96 template <class T> struct is_integral : false_type { };
97 template<> struct is_integral<bool> : true_type { };
98 template<> struct is_integral<char> : true_type { };
99 template<> struct is_integral<unsigned char> : true_type { };
100 template<> struct is_integral<signed char> : true_type { };
101 #if defined(_MSC_VER)
102 // wchar_t is not by default a distinct type from unsigned short in
103 // Microsoft C.
104 // See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
105 template<> struct is_integral<__wchar_t> : true_type { };
106 #else
107 template<> struct is_integral<wchar_t> : true_type { };
108 #endif
109 template<> struct is_integral<short> : true_type { };
110 template<> struct is_integral<unsigned short> : true_type { };
111 template<> struct is_integral<int> : true_type { };
112 template<> struct is_integral<unsigned int> : true_type { };
113 template<> struct is_integral<long> : true_type { };
114 template<> struct is_integral<unsigned long> : true_type { };
115 #ifdef HAVE_LONG_LONG
116 template<> struct is_integral<long long> : true_type { };
117 template<> struct is_integral<unsigned long long> : true_type { };
118 #endif
119 template <class T> struct is_integral<const T> : is_integral<T> { };
120 template <class T> struct is_integral<volatile T> : is_integral<T> { };
121 template <class T> struct is_integral<const volatile T> : is_integral<T> { };
122 
123 // is_floating_point is false except for the built-in floating-point types.
124 // A cv-qualified type is integral if and only if the underlying type is.
125 template <class T> struct is_floating_point : false_type { };
126 template<> struct is_floating_point<float> : true_type { };
127 template<> struct is_floating_point<double> : true_type { };
128 template<> struct is_floating_point<long double> : true_type { };
129 template <class T> struct is_floating_point<const T>
130  : is_floating_point<T> { };
131 template <class T> struct is_floating_point<volatile T>
132  : is_floating_point<T> { };
133 template <class T> struct is_floating_point<const volatile T>
134  : is_floating_point<T> { };
135 
136 // is_pointer is false except for pointer types. A cv-qualified type (e.g.
137 // "int* const", as opposed to "int const*") is cv-qualified if and only if
138 // the underlying type is.
139 template <class T> struct is_pointer : false_type { };
140 template <class T> struct is_pointer<T*> : true_type { };
141 template <class T> struct is_pointer<const T> : is_pointer<T> { };
142 template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
143 template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
144 
145 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
146 
147 namespace internal {
148 
149 template <class T> struct is_class_or_union {
150  template <class U> static small_ tester(void (U::*)());
151  template <class U> static big_ tester(...);
152  static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
153 };
154 
155 // is_convertible chokes if the first argument is an array. That's why
156 // we use add_reference here.
157 template <bool NotUnum, class T> struct is_enum_impl
158  : is_convertible<typename add_reference<T>::type, int> { };
159 
160 template <class T> struct is_enum_impl<true, T> : false_type { };
161 
162 } // namespace internal
163 
164 // Specified by TR1 [4.5.1] primary type categories.
165 
166 // Implementation note:
167 //
168 // Each type is either void, integral, floating point, array, pointer,
169 // reference, member object pointer, member function pointer, enum,
170 // union or class. Out of these, only integral, floating point, reference,
171 // class and enum types are potentially convertible to int. Therefore,
172 // if a type is not a reference, integral, floating point or class and
173 // is convertible to int, it's a enum. Adding cv-qualification to a type
174 // does not change whether it's an enum.
175 //
176 // Is-convertible-to-int check is done only if all other checks pass,
177 // because it can't be used with some types (e.g. void or classes with
178 // inaccessible conversion operators).
179 template <class T> struct is_enum
181  is_same<T, void>::value ||
182  is_integral<T>::value ||
183  is_floating_point<T>::value ||
184  is_reference<T>::value ||
185  internal::is_class_or_union<T>::value,
186  T> { };
187 
188 template <class T> struct is_enum<const T> : is_enum<T> { };
189 template <class T> struct is_enum<volatile T> : is_enum<T> { };
190 template <class T> struct is_enum<const volatile T> : is_enum<T> { };
191 
192 #endif
193 
194 // is_reference is false except for reference types.
195 template<typename T> struct is_reference : false_type {};
196 template<typename T> struct is_reference<T&> : true_type {};
197 
198 
199 // We can't get is_pod right without compiler help, so fail conservatively.
200 // We will assume it's false except for arithmetic types, enumerations,
201 // pointers and cv-qualified versions thereof. Note that std::pair<T,U>
202 // is not a POD even if T and U are PODs.
203 template <class T> struct is_pod
204  : integral_constant<bool, (is_integral<T>::value ||
205  is_floating_point<T>::value ||
206 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
207  // is_enum is not available on MSVC.
208  is_enum<T>::value ||
209 #endif
210  is_pointer<T>::value)> { };
211 template <class T> struct is_pod<const T> : is_pod<T> { };
212 template <class T> struct is_pod<volatile T> : is_pod<T> { };
213 template <class T> struct is_pod<const volatile T> : is_pod<T> { };
214 
215 
216 // We can't get has_trivial_constructor right without compiler help, so
217 // fail conservatively. We will assume it's false except for: (1) types
218 // for which is_pod is true. (2) std::pair of types with trivial
219 // constructors. (3) array of a type with a trivial constructor.
220 // (4) const versions thereof.
221 template <class T> struct has_trivial_constructor : is_pod<T> { };
222 template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
223  : integral_constant<bool,
224  (has_trivial_constructor<T>::value &&
225  has_trivial_constructor<U>::value)> { };
226 template <class A, int N> struct has_trivial_constructor<A[N]>
227  : has_trivial_constructor<A> { };
228 template <class T> struct has_trivial_constructor<const T>
229  : has_trivial_constructor<T> { };
230 
231 // We can't get has_trivial_copy right without compiler help, so fail
232 // conservatively. We will assume it's false except for: (1) types
233 // for which is_pod is true. (2) std::pair of types with trivial copy
234 // constructors. (3) array of a type with a trivial copy constructor.
235 // (4) const versions thereof.
236 template <class T> struct has_trivial_copy : is_pod<T> { };
237 template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
238  : integral_constant<bool,
239  (has_trivial_copy<T>::value &&
240  has_trivial_copy<U>::value)> { };
241 template <class A, int N> struct has_trivial_copy<A[N]>
242  : has_trivial_copy<A> { };
243 template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
244 
245 // We can't get has_trivial_assign right without compiler help, so fail
246 // conservatively. We will assume it's false except for: (1) types
247 // for which is_pod is true. (2) std::pair of types with trivial copy
248 // constructors. (3) array of a type with a trivial assign constructor.
249 template <class T> struct has_trivial_assign : is_pod<T> { };
250 template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
251  : integral_constant<bool,
252  (has_trivial_assign<T>::value &&
253  has_trivial_assign<U>::value)> { };
254 template <class A, int N> struct has_trivial_assign<A[N]>
255  : has_trivial_assign<A> { };
256 
257 // We can't get has_trivial_destructor right without compiler help, so
258 // fail conservatively. We will assume it's false except for: (1) types
259 // for which is_pod is true. (2) std::pair of types with trivial
260 // destructors. (3) array of a type with a trivial destructor.
261 // (4) const versions thereof.
262 template <class T> struct has_trivial_destructor : is_pod<T> { };
263 template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
264  : integral_constant<bool,
265  (has_trivial_destructor<T>::value &&
266  has_trivial_destructor<U>::value)> { };
267 template <class A, int N> struct has_trivial_destructor<A[N]>
268  : has_trivial_destructor<A> { };
269 template <class T> struct has_trivial_destructor<const T>
270  : has_trivial_destructor<T> { };
271 
272 // Specified by TR1 [4.7.1]
273 template<typename T> struct remove_const { typedef T type; };
274 template<typename T> struct remove_const<T const> { typedef T type; };
275 template<typename T> struct remove_volatile { typedef T type; };
276 template<typename T> struct remove_volatile<T volatile> { typedef T type; };
277 template<typename T> struct remove_cv {
278  typedef typename remove_const<typename remove_volatile<T>::type>::type type;
279 };
280 
281 
282 // Specified by TR1 [4.7.2] Reference modifications.
283 template<typename T> struct remove_reference { typedef T type; };
284 template<typename T> struct remove_reference<T&> { typedef T type; };
285 
286 template <typename T> struct add_reference { typedef T& type; };
287 template <typename T> struct add_reference<T&> { typedef T& type; };
288 
289 // Specified by TR1 [4.7.4] Pointer modifications.
290 template<typename T> struct remove_pointer { typedef T type; };
291 template<typename T> struct remove_pointer<T*> { typedef T type; };
292 template<typename T> struct remove_pointer<T* const> { typedef T type; };
293 template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
294 template<typename T> struct remove_pointer<T* const volatile> {
295  typedef T type; };
296 
297 // Specified by TR1 [4.6] Relationships between types
298 template<typename T, typename U> struct is_same : public false_type { };
299 template<typename T> struct is_same<T, T> : public true_type { };
300 
301 // Specified by TR1 [4.6] Relationships between types
302 #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
303 namespace internal {
304 
305 // This class is an implementation detail for is_convertible, and you
306 // don't need to know how it works to use is_convertible. For those
307 // who care: we declare two different functions, one whose argument is
308 // of type To and one with a variadic argument list. We give them
309 // return types of different size, so we can use sizeof to trick the
310 // compiler into telling us which function it would have chosen if we
311 // had called it with an argument of type From. See Alexandrescu's
312 // _Modern C++ Design_ for more details on this sort of trick.
313 
314 template <typename From, typename To>
315 struct ConvertHelper {
316  static small_ Test(To);
317  static big_ Test(...);
318  static From Create();
319 };
320 } // namespace internal
321 
322 // Inherits from true_type if From is convertible to To, false_type otherwise.
323 template <typename From, typename To>
324 struct is_convertible
325  : integral_constant<bool,
326  sizeof(internal::ConvertHelper<From, To>::Test(
327  internal::ConvertHelper<From, To>::Create()))
328  == sizeof(small_)> {
329 };
330 #endif
331 
332 } // namespace internal
333 } // namespace protobuf
334 } // namespace google
335 
336 #endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_
integral_constant< bool, true > true_type
Definition: template_util.h:89
Definition: type_traits.h:78
Definition: type_traits.h:83
Definition: type_traits.h:88
Definition: type_traits.h:91
Definition: type_traits.h:69
Definition: type_traits.h:89
#define bool
Definition: CascPort.h:16
Definition: type_traits.h:85
#define true
Definition: CascPort.h:17
Definition: template_util.h:61
Definition: type_traits.h:75
Definition: template_util.h:77
Definition: type_traits.h:71
char small_
Definition: template_util.h:59
Definition: type_traits.h:87
Definition: document.h:390
Definition: type_traits.h:77
Definition: BnetFileGenerator.h:47
#define const
Definition: zconf.h:217
static const bool value
Definition: type_traits.h:152