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