173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian/* 273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * Copyright (C) 2011 The Android Open Source Project 373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * 473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * you may not use this file except in compliance with the License. 673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * You may obtain a copy of the License at 773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * 873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * 1073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * Unless required by applicable law or agreed to in writing, software 1173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * See the License for the specific language governing permissions and 1473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian * limitations under the License. 1573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian */ 1673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 1773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#ifndef ANDROID_TRAITS_H 1873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define ANDROID_TRAITS_H 1973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 2173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// Typelists 2273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiannamespace android { 2473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// end-of-list marker 2673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianclass NullType {}; 2773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 2873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// type-list node 2973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T, typename U> 3073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct TypeList { 3173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef T Head; 3273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef U Tail; 3373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 3473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 3573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// helpers to build typelists 3673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define TYPELIST_1(T1) TypeList<T1, NullType> 3773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)> 3873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)> 3973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)> 4073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 4173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// typelists algorithms 4273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiannamespace TL { 4373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename TList, typename T> struct IndexOf; 4473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 4573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T> 4673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct IndexOf<NullType, T> { 4773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { value = -1 }; 4873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 4973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 5073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T, typename Tail> 5173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct IndexOf<TypeList<T, Tail>, T> { 5273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { value = 0 }; 5373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 5473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 5573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename Head, typename Tail, typename T> 5673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct IndexOf<TypeList<Head, Tail>, T> { 5773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianprivate: 5873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { temp = IndexOf<Tail, T>::value }; 5973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianpublic: 6073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { value = temp == -1 ? -1 : 1 + temp }; 6173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 6273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 6373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; // namespace TL 6473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 6573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// type selection based on a boolean 6673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <bool flag, typename T, typename U> 6773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct Select { 6873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef T Result; 6973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 7073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T, typename U> 7173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianstruct Select<false, T, U> { 7273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef U Result; 7373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 7473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 7573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 7673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// Type traits 7773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 7873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopiantemplate <typename T> 7973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianclass TypeTraits { 8073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPELIST_4( 8173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian unsigned char, unsigned short, 8273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian unsigned int, unsigned long int) UnsignedInts; 8373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 8473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPELIST_4( 8573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian signed char, signed short, 8673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian signed int, signed long int) SignedInts; 8773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 8873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPELIST_1( 8973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian bool) OtherInts; 9073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 9173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef TYPELIST_3( 9273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian float, double, long double) Floats; 9373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 9473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename U> struct PointerTraits { 9573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { result = false }; 9673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef NullType PointeeType; 9773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian }; 9873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian template<typename U> struct PointerTraits<U*> { 9973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { result = true }; 10073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef U PointeeType; 10173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian }; 10273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 10373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopianpublic: 10473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 }; 10573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { isStdSignedInt = TL::IndexOf<SignedInts, T>::value >= 0 }; 10673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { isStdIntegral = TL::IndexOf<OtherInts, T>::value >= 0 || isStdUnsignedInt || isStdSignedInt }; 10773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { isStdFloat = TL::IndexOf<Floats, T>::value >= 0 }; 10873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { isPointer = PointerTraits<T>::result }; 10973e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian enum { isStdArith = isStdIntegral || isStdFloat }; 11073e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 11173e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian // best parameter type for given type 11273e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType; 11373e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; 11473e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 11573e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian// ----------------------------------------------------------------------- 11673e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian}; // namespace android 11773e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian 11873e0bc805a143d8cc2202fccb73230459edc6869Mathias Agopian#endif /* ANDROID_TRAITS_H */ 119