1984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian/* 2984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Copyright (C) 2011 The Android Open Source Project 3984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 4984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * you may not use this file except in compliance with the License. 6984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * You may obtain a copy of the License at 7984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 8984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 10984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Unless required by applicable law or agreed to in writing, software 11984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * See the License for the specific language governing permissions and 14984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * limitations under the License. 15984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian */ 16984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 17984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#ifndef ANDROID_TRAITS_H 18984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define ANDROID_TRAITS_H 19984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 20984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 21984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Typelists 22984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 23984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace android { 24984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 25984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// end-of-list marker 26984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass NullType {}; 27984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 28984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// type-list node 29984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T, typename U> 30984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct TypeList { 31984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef T Head; 32984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef U Tail; 33984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 34984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// helpers to build typelists 36984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_1(T1) TypeList<T1, NullType> 37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)> 38984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)> 39984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)> 40984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 41984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// typelists algorithms 42984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace TL { 43984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TList, typename T> struct IndexOf; 44984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 45984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T> 46984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct IndexOf<NullType, T> { 47984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { value = -1 }; 48984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 49984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T, typename Tail> 51984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct IndexOf<TypeList<T, Tail>, T> { 52984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { value = 0 }; 53984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 54984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 55984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename Head, typename Tail, typename T> 56984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct IndexOf<TypeList<Head, Tail>, T> { 57984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianprivate: 58984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { temp = IndexOf<Tail, T>::value }; 59984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic: 60984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { value = temp == -1 ? -1 : 1 + temp }; 61984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 62984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 63984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace TL 64984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 65984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// type selection based on a boolean 66984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <bool flag, typename T, typename U> 67984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct Select { 68984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef T Result; 69984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 70984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T, typename U> 71984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct Select<false, T, U> { 72984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef U Result; 73984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 74984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 75984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 76984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Type traits 77984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 78984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T> 79984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass TypeTraits { 80984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPELIST_4( 81984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian unsigned char, unsigned short, 82984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian unsigned int, unsigned long int) UnsignedInts; 83984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 84984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPELIST_4( 85984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian signed char, signed short, 86984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian signed int, signed long int) SignedInts; 87984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 88984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPELIST_1( 89984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian bool) OtherInts; 90984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 91984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPELIST_3( 92984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian float, double, long double) Floats; 93984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 94984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename U> struct PointerTraits { 95984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { result = false }; 96984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef NullType PointeeType; 97984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian }; 98984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename U> struct PointerTraits<U*> { 99984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { result = true }; 100984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef U PointeeType; 101984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian }; 102984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 103984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic: 104984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 }; 105984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { isStdSignedInt = TL::IndexOf<SignedInts, T>::value >= 0 }; 106984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { isStdIntegral = TL::IndexOf<OtherInts, T>::value >= 0 || isStdUnsignedInt || isStdSignedInt }; 107984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { isStdFloat = TL::IndexOf<Floats, T>::value >= 0 }; 108984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { isPointer = PointerTraits<T>::result }; 109984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { isStdArith = isStdIntegral || isStdFloat }; 110984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 111984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // best parameter type for given type 112984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType; 113984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 114984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 115984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 116984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace android 117984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 118984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#endif /* ANDROID_TRAITS_H */ 119