1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_TRAITS_H 18 #define ANDROID_TRAITS_H 19 20 // ----------------------------------------------------------------------- 21 // Typelists 22 23 namespace android { 24 25 // end-of-list marker 26 class NullType {}; 27 28 // type-list node 29 template <typename T, typename U> 30 struct TypeList { 31 typedef T Head; 32 typedef U Tail; 33 }; 34 35 // helpers to build typelists 36 #define TYPELIST_1(T1) TypeList<T1, NullType> 37 #define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)> 38 #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)> 39 #define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)> 40 41 // typelists algorithms 42 namespace TL { 43 template <typename TList, typename T> struct IndexOf; 44 45 template <typename T> 46 struct IndexOf<NullType, T> { 47 enum { value = -1 }; 48 }; 49 50 template <typename T, typename Tail> 51 struct IndexOf<TypeList<T, Tail>, T> { 52 enum { value = 0 }; 53 }; 54 55 template <typename Head, typename Tail, typename T> 56 struct IndexOf<TypeList<Head, Tail>, T> { 57 private: 58 enum { temp = IndexOf<Tail, T>::value }; 59 public: 60 enum { value = temp == -1 ? -1 : 1 + temp }; 61 }; 62 63 }; // namespace TL 64 65 // type selection based on a boolean 66 template <bool flag, typename T, typename U> 67 struct Select { 68 typedef T Result; 69 }; 70 template <typename T, typename U> 71 struct Select<false, T, U> { 72 typedef U Result; 73 }; 74 75 // ----------------------------------------------------------------------- 76 // Type traits 77 78 template <typename T> 79 class TypeTraits { 80 typedef TYPELIST_4( 81 unsigned char, unsigned short, 82 unsigned int, unsigned long int) UnsignedInts; 83 84 typedef TYPELIST_4( 85 signed char, signed short, 86 signed int, signed long int) SignedInts; 87 88 typedef TYPELIST_1( 89 bool) OtherInts; 90 91 typedef TYPELIST_3( 92 float, double, long double) Floats; 93 94 template<typename U> struct PointerTraits { 95 enum { result = false }; 96 typedef NullType PointeeType; 97 }; 98 template<typename U> struct PointerTraits<U*> { 99 enum { result = true }; 100 typedef U PointeeType; 101 }; 102 103 public: 104 enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 }; 105 enum { isStdSignedInt = TL::IndexOf<SignedInts, T>::value >= 0 }; 106 enum { isStdIntegral = TL::IndexOf<OtherInts, T>::value >= 0 || isStdUnsignedInt || isStdSignedInt }; 107 enum { isStdFloat = TL::IndexOf<Floats, T>::value >= 0 }; 108 enum { isPointer = PointerTraits<T>::result }; 109 enum { isStdArith = isStdIntegral || isStdFloat }; 110 111 // best parameter type for given type 112 typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType; 113 }; 114 115 // ----------------------------------------------------------------------- 116 }; // namespace android 117 118 #endif /* ANDROID_TRAITS_H */ 119