|  | /* | 
|  | * Copyright (C) 2011 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #ifndef ANDROID_TRAITS_H | 
|  | #define ANDROID_TRAITS_H | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | // Typelists | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | // end-of-list marker | 
|  | class NullType {}; | 
|  |  | 
|  | // type-list node | 
|  | template <typename T, typename U> | 
|  | struct TypeList { | 
|  | typedef T Head; | 
|  | typedef U Tail; | 
|  | }; | 
|  |  | 
|  | // helpers to build typelists | 
|  | #define TYPELIST_1(T1) TypeList<T1, NullType> | 
|  | #define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)> | 
|  | #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)> | 
|  | #define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)> | 
|  |  | 
|  | // typelists algorithms | 
|  | namespace TL { | 
|  | template <typename TList, typename T> struct IndexOf; | 
|  |  | 
|  | template <typename T> | 
|  | struct IndexOf<NullType, T> { | 
|  | enum { value = -1 }; | 
|  | }; | 
|  |  | 
|  | template <typename T, typename Tail> | 
|  | struct IndexOf<TypeList<T, Tail>, T> { | 
|  | enum { value = 0 }; | 
|  | }; | 
|  |  | 
|  | template <typename Head, typename Tail, typename T> | 
|  | struct IndexOf<TypeList<Head, Tail>, T> { | 
|  | private: | 
|  | enum { temp = IndexOf<Tail, T>::value }; | 
|  | public: | 
|  | enum { value = temp == -1 ? -1 : 1 + temp }; | 
|  | }; | 
|  |  | 
|  | }; // namespace TL | 
|  |  | 
|  | // type selection based on a boolean | 
|  | template <bool flag, typename T, typename U> | 
|  | struct Select { | 
|  | typedef T Result; | 
|  | }; | 
|  | template <typename T, typename U> | 
|  | struct Select<false, T, U> { | 
|  | typedef U Result; | 
|  | }; | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | // Type traits | 
|  |  | 
|  | template <typename T> | 
|  | class TypeTraits { | 
|  | typedef TYPELIST_4( | 
|  | unsigned char, unsigned short, | 
|  | unsigned int, unsigned long int) UnsignedInts; | 
|  |  | 
|  | typedef TYPELIST_4( | 
|  | signed char, signed short, | 
|  | signed int, signed long int) SignedInts; | 
|  |  | 
|  | typedef TYPELIST_1( | 
|  | bool) OtherInts; | 
|  |  | 
|  | typedef TYPELIST_3( | 
|  | float, double, long double) Floats; | 
|  |  | 
|  | template<typename U> struct PointerTraits { | 
|  | enum { result = false }; | 
|  | typedef NullType PointeeType; | 
|  | }; | 
|  | template<typename U> struct PointerTraits<U*> { | 
|  | enum { result = true }; | 
|  | typedef U PointeeType; | 
|  | }; | 
|  |  | 
|  | public: | 
|  | enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 }; | 
|  | enum { isStdSignedInt   = TL::IndexOf<SignedInts,   T>::value >= 0 }; | 
|  | enum { isStdIntegral    = TL::IndexOf<OtherInts,    T>::value >= 0 || isStdUnsignedInt || isStdSignedInt }; | 
|  | enum { isStdFloat       = TL::IndexOf<Floats,       T>::value >= 0 }; | 
|  | enum { isPointer        = PointerTraits<T>::result }; | 
|  | enum { isStdArith       = isStdIntegral || isStdFloat }; | 
|  |  | 
|  | // best parameter type for given type | 
|  | typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType; | 
|  | }; | 
|  |  | 
|  | // ----------------------------------------------------------------------- | 
|  | }; // namespace android | 
|  |  | 
|  | #endif /* ANDROID_TRAITS_H */ |