1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     ut_TypeTraits.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_UT_TYPETRAITS_H_
19 #define NW_UT_TYPETRAITS_H_
20 
21 namespace nw
22 {
23 namespace ut
24 {
25 
26 /*---------------------------------------------------------------------------*
27   internal
28  *---------------------------------------------------------------------------*/
29 namespace internal
30 {
31 
32 template <typename TType, TType Value>
33 struct integral_constant
34 {
35     static const TType value = Value;
36     typedef TType value_type;
37 };
38 
39 typedef integral_constant<bool, true>  TrueType;
40 typedef integral_constant<bool, false> FalseType;
41 
42 template<bool Cond, typename Then, typename Else>
43 struct IfCond;
44 
45 template<typename Then, typename Else>
46 struct IfCond<true, Then, Else>
47 {
48     typedef Then type;
49 };
50 
51 template<typename Then, typename Else>
52 struct IfCond<false, Then, Else>
53 {
54     typedef Else type;
55 };
56 
57 struct True  { char a;    };
58 struct False { True  a[2]; };
59 
60 }
61 
62 /*---------------------------------------------------------------------------*
63   declare_type_remove_template
64  *---------------------------------------------------------------------------*/
65 #define NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_BASE_(name, ttype)  \
66 template<typename ttype>                                       \
67 struct name                                                    \
68 {                                                              \
69     typedef ttype type;                                        \
70 };
71 
72 #define NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_(name, ttype, modifier) \
73 template<typename ttype>                                           \
74 struct name<modifier>                                              \
75 {                                                                  \
76     typedef TType type;                                            \
77 };
78 
79 #define NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE2_(name, ttype, modifier, ...) \
80 template<typename __VA_ARGS__>                                           \
81 struct name<modifier>                                                    \
82 {                                                                        \
83     typedef TType type;                                                  \
84 };
85 
86 /*---------------------------------------------------------------------------*
87   remove_bounds
88  *---------------------------------------------------------------------------*/
89 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_BASE_(remove_bounds, TType)
90 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_(remove_bounds, TType, TType[])
91 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE2_(remove_bounds, TType, TType[Size], TType, int Size)
92 
93 /*---------------------------------------------------------------------------*
94   remove_const
95  *---------------------------------------------------------------------------*/
96 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_BASE_(remove_const, TType)
97 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_(remove_const, TType, const TType)
98 
99 /*---------------------------------------------------------------------------*
100   remove_reference
101  *---------------------------------------------------------------------------*/
102 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_BASE_(remove_reference, TType)
103 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_(remove_reference, TType, TType&)
104 
105 /*---------------------------------------------------------------------------*
106   remove_pointer
107  *---------------------------------------------------------------------------*/
108 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_BASE_(remove_pointer, TType)
109 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_(remove_pointer, TType, TType*)
110 NW_UT_DECLARE_TYPE_REMOVE_TEMPLATE_(remove_pointer, TType, TType* const)
111 
112 /*---------------------------------------------------------------------------*
113   Is_*
114  *---------------------------------------------------------------------------*/
115 #define NW_TRAITS_SPEC0(Spec, Value) \
116     template <> \
117     struct Spec : public internal::integral_constant<bool, Value> {};
118 
119 #define NW_TRAITS_SPEC1(Spec, Value) \
120     template <typename Type> \
121     struct Spec : public internal::integral_constant<bool, Value> {};
122 
123 #define NW_TRAITS_SPEC2(Spec, Value) \
124     template <typename Type, typename ClassName> \
125     struct Spec : public internal::integral_constant<bool, Value> {};
126 
127 #define NW_TRAITS_SPEC(Order, Traits, SpecialType, Value)            \
128     NW_TRAITS_SPEC##Order(Traits<SpecialType>,                Value) \
129     NW_TRAITS_SPEC##Order(Traits<SpecialType const>,          Value) \
130     NW_TRAITS_SPEC##Order(Traits<SpecialType volatile>,       Value) \
131     NW_TRAITS_SPEC##Order(Traits<SpecialType const volatile>, Value)
132 
133 /*---------------------------------------------------------------------------*
134   IsArray
135  *---------------------------------------------------------------------------*/
136 template <typename TType>
137 struct IsArray : public internal::FalseType {};
138 
139 template <typename TType, int Size>
140 struct IsArray<TType[Size]> : public internal::TrueType {};
141 
142 template <typename TType>
143 struct IsArray<TType[]> : public internal::TrueType {};
144 
145 /*---------------------------------------------------------------------------*
146   IsPointer
147  *---------------------------------------------------------------------------*/
148 template <typename Type>
149 struct IsPointer : public internal::FalseType {};
150 NW_TRAITS_SPEC(1, IsPointer, Type*, true)
151 
152 /*---------------------------------------------------------------------------*
153   IsSame
154  *---------------------------------------------------------------------------*/
155 template <typename, typename>
156 struct IsSame : public internal::FalseType {};
157 
158 template <typename Type>
159 struct IsSame<Type, Type> : public internal::TrueType {};
160 
161 /*---------------------------------------------------------------------------*
162   IsClass
163  *---------------------------------------------------------------------------*/
164 template <class T>
165 struct IsClass
166 {
167     template <class C> static internal::True test(int C::*);
168     template <class C> static internal::False test(...);
169     static const bool value = (sizeof(test<T>(0)) == sizeof(internal::True));
170 };
171 
172 /*---------------------------------------------------------------------------*
173   _if
174  *---------------------------------------------------------------------------*/
175 template<typename Cond, typename Then, typename Else>
176 struct If_ : public internal::IfCond<Cond::value, Then, Else> {};
177 
178 } // namespace ut
179 } // namespace nw
180 
181 #endif // NW_UT_TYPETRAITS_H_
182