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