1984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian/*
2984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Copyright (C) 2011 The Android Open Source Project
3984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian *
4984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * you may not use this file except in compliance with the License.
6984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * You may obtain a copy of the License at
7984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian *
8984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian *
10984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Unless required by applicable law or agreed to in writing, software
11984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * See the License for the specific language governing permissions and
14984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * limitations under the License.
15984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian */
16984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
17984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#ifndef ANDROID_TRAITS_H
18984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define ANDROID_TRAITS_H
19984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
20984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// -----------------------------------------------------------------------
21984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Typelists
22984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
23984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace android {
24984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
25984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// end-of-list marker
26984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass NullType {};
27984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
28984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// type-list node
29984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T, typename U>
30984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct TypeList {
31984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef T Head;
32984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef U Tail;
33984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
34984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// helpers to build typelists
36984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_1(T1) TypeList<T1, NullType>
37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)>
38984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)>
39984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)>
40984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
41984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// typelists algorithms
42984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace TL {
43984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TList, typename T> struct IndexOf;
44984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
45984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T>
46984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct IndexOf<NullType, T> {
47984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { value = -1 };
48984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
49984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T, typename Tail>
51984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct IndexOf<TypeList<T, Tail>, T> {
52984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { value = 0 };
53984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
54984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
55984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename Head, typename Tail, typename T>
56984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct IndexOf<TypeList<Head, Tail>, T> {
57984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianprivate:
58984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { temp = IndexOf<Tail, T>::value };
59984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic:
60984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { value = temp == -1 ? -1 : 1 + temp };
61984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
62984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
63984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace TL
64984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
65984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// type selection based on a boolean
66984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <bool flag, typename T, typename U>
67984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct Select {
68984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef T Result;
69984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
70984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T, typename U>
71984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianstruct Select<false, T, U> {
72984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef U Result;
73984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
74984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
75984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// -----------------------------------------------------------------------
76984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Type traits
77984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
78984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename T>
79984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass TypeTraits {
80984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef TYPELIST_4(
81984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            unsigned char, unsigned short,
82984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            unsigned int, unsigned long int) UnsignedInts;
83984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
84984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef TYPELIST_4(
85984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            signed char, signed short,
86984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            signed int, signed long int) SignedInts;
87984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
88984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef TYPELIST_1(
89984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            bool) OtherInts;
90984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
91984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef TYPELIST_3(
92984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            float, double, long double) Floats;
93984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
94984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    template<typename U> struct PointerTraits {
95984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian        enum { result = false };
96984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian        typedef NullType PointeeType;
97984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    };
98984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    template<typename U> struct PointerTraits<U*> {
99984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian        enum { result = true };
100984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian        typedef U PointeeType;
101984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    };
102984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
103984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic:
104984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 };
105984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { isStdSignedInt   = TL::IndexOf<SignedInts,   T>::value >= 0 };
106984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { isStdIntegral    = TL::IndexOf<OtherInts,    T>::value >= 0 || isStdUnsignedInt || isStdSignedInt };
107984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { isStdFloat       = TL::IndexOf<Floats,       T>::value >= 0 };
108984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { isPointer        = PointerTraits<T>::result };
109984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    enum { isStdArith       = isStdIntegral || isStdFloat };
110984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
111984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    // best parameter type for given type
112984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian    typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType;
113984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian};
114984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
115984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// -----------------------------------------------------------------------
116984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace android
117984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
118984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#endif /* ANDROID_TRAITS_H */
119