1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_TRAITS_H
18 #define ANDROID_TRAITS_H
19 
20 // -----------------------------------------------------------------------
21 // Typelists
22 
23 namespace android {
24 
25 // end-of-list marker
26 class NullType {};
27 
28 // type-list node
29 template <typename T, typename U>
30 struct TypeList {
31     typedef T Head;
32     typedef U Tail;
33 };
34 
35 // helpers to build typelists
36 #define TYPELIST_1(T1) TypeList<T1, NullType>
37 #define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)>
38 #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)>
39 #define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)>
40 
41 // typelists algorithms
42 namespace TL {
43 template <typename TList, typename T> struct IndexOf;
44 
45 template <typename T>
46 struct IndexOf<NullType, T> {
47     enum { value = -1 };
48 };
49 
50 template <typename T, typename Tail>
51 struct IndexOf<TypeList<T, Tail>, T> {
52     enum { value = 0 };
53 };
54 
55 template <typename Head, typename Tail, typename T>
56 struct IndexOf<TypeList<Head, Tail>, T> {
57 private:
58     enum { temp = IndexOf<Tail, T>::value };
59 public:
60     enum { value = temp == -1 ? -1 : 1 + temp };
61 };
62 
63 }; // namespace TL
64 
65 // type selection based on a boolean
66 template <bool flag, typename T, typename U>
67 struct Select {
68     typedef T Result;
69 };
70 template <typename T, typename U>
71 struct Select<false, T, U> {
72     typedef U Result;
73 };
74 
75 // -----------------------------------------------------------------------
76 // Type traits
77 
78 template <typename T>
79 class TypeTraits {
80     typedef TYPELIST_4(
81             unsigned char, unsigned short,
82             unsigned int, unsigned long int) UnsignedInts;
83 
84     typedef TYPELIST_4(
85             signed char, signed short,
86             signed int, signed long int) SignedInts;
87 
88     typedef TYPELIST_1(
89             bool) OtherInts;
90 
91     typedef TYPELIST_3(
92             float, double, long double) Floats;
93 
94     template<typename U> struct PointerTraits {
95         enum { result = false };
96         typedef NullType PointeeType;
97     };
98     template<typename U> struct PointerTraits<U*> {
99         enum { result = true };
100         typedef U PointeeType;
101     };
102 
103 public:
104     enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 };
105     enum { isStdSignedInt   = TL::IndexOf<SignedInts,   T>::value >= 0 };
106     enum { isStdIntegral    = TL::IndexOf<OtherInts,    T>::value >= 0 || isStdUnsignedInt || isStdSignedInt };
107     enum { isStdFloat       = TL::IndexOf<Floats,       T>::value >= 0 };
108     enum { isPointer        = PointerTraits<T>::result };
109     enum { isStdArith       = isStdIntegral || isStdFloat };
110 
111     // best parameter type for given type
112     typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType;
113 };
114 
115 // -----------------------------------------------------------------------
116 }; // namespace android
117 
118 #endif /* ANDROID_TRAITS_H */
119