1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) 2012 Nintendo. All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 
13 #ifndef NN_UTIL_UTIL_TYPETRAITS_H_
14 #define NN_UTIL_UTIL_TYPETRAITS_H_
15 
16 namespace nn { namespace tr1 {
17 
18 // Declaration Section
19 // For implementations, remove these comments.
20 // Do not write implementations here.
21 
22 // [20.4.3] helper class:
23 template <class T, T v> struct integral_constant;
24 typedef integral_constant<bool, true> true_type;
25 typedef integral_constant<bool, false> false_type;
26 
27 // [20.4.4.1] primary type categories:
28 template <class T> struct is_void;
29 template <class T> struct is_integral;
30 template <class T> struct is_floating_point;
31 template <class T> struct is_float;
32 //template <class T> struct is_array;
33 template <class T> struct is_pointer;
34 //template <class T> struct is_lvalue_reference;
35 //template <class T> struct is_rvalue_reference;
36 //template <class T> struct is_member_object_pointer;
37 //template <class T> struct is_member_function_pointer;
38 //template <class T> struct is_enum;
39 //template <class T> struct is_union;
40 //template <class T> struct is_class;
41 //template <class T> struct is_function;
42 
43 // [20.4.4.2] composite type categories:
44 //template <class T> struct is_reference;
45 template <class T> struct is_arithmetic;
46 template <class T> struct is_fundamental;
47 //template <class T> struct is_object;
48 //template <class T> struct is_scalar;
49 //template <class T> struct is_compound;
50 //template <class T> struct is_member_pointer;
51 
52 // [20.4.4.3] type properties:
53 //template <class T> struct is_const;
54 //template <class T> struct is_volatile;
55 //template <class T> struct is_trivial;
56 //template <class T> struct is_standard_layout;
57 //template <class T> struct is_pod;
58 template <class T> struct is_empty;
59 template <class T> struct is_polymorphic;
60 //template <class T> struct is_abstract;
61 //template <class T> struct has_trivial_default_constructor;
62 //template <class T> struct has_trivial_copy_constructor;
63 //template <class T> struct has_trivial_assign;
64 //template <class T> struct has_trivial_destructor;
65 //template <class T> struct has_nothrow_default_constructor;
66 //template <class T> struct has_nothrow_copy_constructor;
67 //template <class T> struct has_nothrow_assign;
68 //template <class T> struct has_virtual_destructor;
69 //template <class T> struct is_signed;
70 //template <class T> struct is_unsigned;
71 template <class T> struct alignment_of;
72 //template <class T> struct rank;
73 //template <class T, unsigned I = 0> struct extent;
74 
75 // [20.4.5] type relations:
76 template <class T, class U> struct is_same;
77 template <class Base, class Derived> struct is_base_of;
78 template <class From, class To> struct is_convertible;
79 
80 // [20.4.6.1] const-volatile modifications:
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 add_const;
85 template <class T> struct add_volatile;
86 template <class T> struct add_cv;
87 
88 // [20.4.6.2] reference modifications:
89 template <class T> struct remove_reference;
90 template <class T> struct add_lvalue_reference;
91 //template <class T> struct add_rvalue_reference;
92 
93 // [20.4.6.3] sign modifications:
94 //template <class T> struct make_signed;
95 //template <class T> struct make_unsigned;
96 
97 // [20.4.6.4] array modifications:
98 //template <class T> struct remove_extent;
99 //template <class T> struct remove_all_extents;
100 
101 // [20.4.6.5] pointer modifications:
102 template <class T> struct remove_pointer;
103 template <class T> struct add_pointer;
104 
105 // [20.4.7] other transformations:
106 template <size_t Len, size_t Align> struct aligned_storage;
107 //template <size_t Len, class... Types> struct aligned_union;
108 //template <class T> struct decay;
109 template <bool, class T = void> struct enable_if;
110 //template <bool, class T, class F> struct conditional;
111 
112 
113 // The implementation section starts here.
114 
115 
116 template <class T>
117 struct type_constant
118 {
119     typedef T type;
120     typedef type Type;
121 protected:
122     ~type_constant();
123 };
124 
125 // template <class T, T v> struct integral_constant; implementation
126 
127 template <class T, T v>
128 struct integral_constant : public type_constant<integral_constant<T, v> >
129 {
130     typedef T value_type;
131     static const value_type value = v;
132     static const value_type Value = v;
133 protected:
134     ~integral_constant();
135 };
136 
137 
138 // template <class T> struct is_void; implementation
139 // template <class T> struct is_integral; implementation
140 // template <class T> struct is_floating_point; implementation
141 // template <class T> struct is_arithmetic; implementation
142 // template <class T> struct is_fundamental; implementation
143 
144 namespace detail
145 {
146     // If compiler errors occur, remove that line.
147 
148     template <class>
149     struct is_void_impl : public false_type {};
150 
151     template <> struct is_void_impl<void> : public true_type {};
152 
153     template <class>
154     struct is_integral_impl : public false_type {};
155 
156     template <> struct is_integral_impl<bool> : public true_type {};
157     template <> struct is_integral_impl<char> : public true_type {};
158     template <> struct is_integral_impl<wchar_t> : public true_type {};
159     template <> struct is_integral_impl<unsigned char> : public true_type {};
160     template <> struct is_integral_impl<signed char> : public true_type {};
161     template <> struct is_integral_impl<unsigned short> : public true_type {};
162     template <> struct is_integral_impl<signed short> : public true_type {};
163     template <> struct is_integral_impl<unsigned int> : public true_type {};
164     template <> struct is_integral_impl<signed int> : public true_type {};
165     template <> struct is_integral_impl<unsigned long> : public true_type {};
166     template <> struct is_integral_impl<signed long> : public true_type {};
167     template <> struct is_integral_impl<unsigned long long> : public true_type {};
168     template <> struct is_integral_impl<signed long long> : public true_type {};
169 
170     template <class T> struct is_pointer_impl : public false_type {};
171     template <class T> struct is_pointer_impl<T*> : public true_type {};
172 
173     template <class>
174     struct is_floating_point_impl : public false_type {};
175 
176     template <> struct is_floating_point_impl<float> : public true_type {};
177     template <> struct is_floating_point_impl<double> : public true_type {};
178     template <> struct is_floating_point_impl<long double> : public true_type {};
179 
180 }
181 
182 template <class T>
183 struct is_void : public detail::is_void_impl<typename remove_cv<T>::type> {};
184 
185 template <class T>
186 struct is_integral : public detail::is_integral_impl<typename remove_cv<T>::type> {};
187 
188 template <class T>
189 struct is_float : public detail::is_floating_point_impl<typename remove_cv<T>::type> {};
190 
191 template <class T>
192 struct is_pointer : public detail::is_pointer_impl<typename remove_cv<T>::type> {};
193 
194 template <class T>
195 struct is_floating_point : public detail::is_floating_point_impl<typename remove_cv<T>::type> {};
196 
197 template <class T>
198 struct is_arithmetic : public integral_constant<bool, is_integral<T>::value || is_floating_point<T>::value> {};
199 
200 template <class T>
201 struct is_fundamental : public integral_constant<bool, is_arithmetic<T>::value || is_void<T>::value> {};
202 
203 // template <class T> struct alignment_of; implementation
204 
205 #ifdef NN_COMPILER_RVCT
206 
207 template <class T>
208 struct alignment_of : public integral_constant<size_t, __alignof__(T)> {};
209 
210 #else
211 
212 namespace detail
213 {
214     template <class T>
215     class AlignmentHack
216     {
217         char c;
218         T x;
219     };
220 }
221 
222 template <class T>
223 struct alignment_of : public integral_constant<size_t, sizeof(detail::AlignmentHack<T>) - sizeof(T)> {};
224 
225 #endif
226 
227 // template <size_t Len, size_t Align> struct aligned_storage; implementation
228 
229 namespace detail
230 {
231     template <size_t>
232     struct AlignmentType {};
233 
234     template <>
235     struct AlignmentType<1>
236     {
237         typedef char type;
238     };
239 
240     template <>
241     struct AlignmentType<2>
242     {
243         typedef short type;
244     };
245 
246     template <>
247     struct AlignmentType<4>
248     {
249         typedef int type;
250     };
251 
252     template <>
253     struct AlignmentType<8>
254     {
255         typedef long long type;
256     };
257 }
258 
259 template <size_t Size, size_t Align>
260 struct aligned_storage
261 {
262 private:
263 
264     union UnionType
265     {
266         char c[Size];
267         typename detail::AlignmentType<Align>::type a;
268     };
269 
270 public:
271     typedef UnionType type;
272 };
273 
274 
275 // template <bool b, class T = void> struct enable_if; implementation
276 
277 template <bool, class>
278 struct enable_if {};
279 
280 template <class T>
281 struct enable_if<true, T> { typedef T type; };
282 
283 
284 // template <class From, class To> struct is_convertible; implementation
285 
286 template <class From, class To>
287 struct is_convertible
288 {
289 private:
290 
291     typedef char T1;
292     struct T2 { char dummy[2]; };
293     static T1* IsConvertibleTest(To);
294     static T2* IsConvertibleTest(...);
295     static From MakeFrom();
296 
297 public:
298 
299     typedef bool value_type;
300     static const bool value = sizeof(*IsConvertibleTest(MakeFrom())) == sizeof(T1);
301 
302 };
303 
304 
305 // template <class T, class U> struct is_same; implementation
306 
307 template <class T, class U>
308 struct is_same : public false_type {};
309 
310 template <class T>
311 struct is_same<T, T> : public true_type {};
312 
313 
314 // template <class Base, class Derived> struct is_base_of; implementation
315 
316 template <class Base, class Derived>
317 struct is_base_of : public integral_constant<bool, is_convertible<const Derived*, const Base*>::value && !is_same<const Base*, const void*>::value> {};
318 
319 
320 // template <class T> struct is_empty; implementation
321 // template <class T> struct is_polymorphic; implementation
322 namespace detail {
323     template <class> struct EmptyStruct {};
324     template <class T> struct StaticStruct : public T {};
325     template <class T> struct VirtualStruct : public T { virtual void Dummy(); virtual ~VirtualStruct(); };
326 }
327 
328 template <class T>
329 struct is_empty : public integral_constant<bool, sizeof(detail::StaticStruct<T>) == sizeof(detail::EmptyStruct<T>)> {};
330 
331 template <class T>
332 struct is_polymorphic : public integral_constant<bool, sizeof(detail::StaticStruct<T>) != sizeof(detail::VirtualStruct<T>)> {};
333 
334 
335 // Implementation.
336 // template <class T> struct remove_const;
337 // template <class T> struct remove_volatile;
338 // template <class T> struct remove_cv;
339 // template <class T> struct add_const;
340 // template <class T> struct add_volatile;
341 // template <class T> struct add_cv;
342 
343 
344 template <class T> struct remove_cv : public remove_volatile<typename remove_const<T>::type> {};
345 
346 template <class T> struct remove_const : public type_constant<T> {};
347 template <class T> struct remove_const<const T> : public type_constant<T> {};
348 
349 
350 template <class T> struct remove_volatile : public type_constant<T> {};
351 template <class T> struct remove_volatile<volatile T> : public type_constant<T> {};
352 
353 template <class T> struct add_cv : public add_volatile<typename add_const<T>::type> {};
354 template <class T> struct add_const : public type_constant<const T> {};
355 template <class T> struct add_volatile : public type_constant<volatile T> {};
356 
357 
358 // Implementation.
359 // template <class T> struct remove_reference;
360 // template <class T> struct add_lvalue_reference;
361 
362 template <class T> struct remove_reference : public type_constant<T> {};
363 template <class T> struct remove_reference<T&> : public type_constant<T> {};
364 //template< class T > struct remove_reference<T&&> {typedef T type;};
365 
366 template <class T> struct add_lvalue_reference : public type_constant<typename remove_reference<T>::type&> {};
367 
368 
369 // Implementation.
370 // template <class T> struct remove_pointer;
371 // template <class T> struct add_pointer;
372 
373 template <class T> struct remove_pointer : public type_constant<T> {};
374 template <class T> struct remove_pointer<T*> : public type_constant<T> {};
375 template <class T> struct remove_pointer<T* const> : public type_constant<T> {};
376 template <class T> struct remove_pointer<T* volatile> : public type_constant<T> {};
377 template <class T> struct remove_pointer<T* const volatile> : public type_constant<T> {};
378 
379 template <class T> struct add_pointer : public type_constant<T*> {};
380 
381 }}
382 
383 namespace nn { namespace util {
384     using namespace nn::tr1;
385 }}
386 
387 
388 #endif // include guard
389 
390