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