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