| /* | 
 |  * 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 */ |