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 23namespace android { 24 25// end-of-list marker 26class NullType {}; 27 28// type-list node 29template <typename T, typename U> 30struct 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 42namespace TL { 43template <typename TList, typename T> struct IndexOf; 44 45template <typename T> 46struct IndexOf<NullType, T> { 47 enum { value = -1 }; 48}; 49 50template <typename T, typename Tail> 51struct IndexOf<TypeList<T, Tail>, T> { 52 enum { value = 0 }; 53}; 54 55template <typename Head, typename Tail, typename T> 56struct IndexOf<TypeList<Head, Tail>, T> { 57private: 58 enum { temp = IndexOf<Tail, T>::value }; 59public: 60 enum { value = temp == -1 ? -1 : 1 + temp }; 61}; 62 63}; // namespace TL 64 65// type selection based on a boolean 66template <bool flag, typename T, typename U> 67struct Select { 68 typedef T Result; 69}; 70template <typename T, typename U> 71struct Select<false, T, U> { 72 typedef U Result; 73}; 74 75// ----------------------------------------------------------------------- 76// Type traits 77 78template <typename T> 79class 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 103public: 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