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
23namespace android {
24
25// end-of-list marker
26class NullType {};
27
28// type-list node
29template <typename T, typename U>
30struct 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
42namespace TL {
43template <typename TList, typename T> struct IndexOf;
44
45template <typename T>
46struct IndexOf<NullType, T> {
47    enum { value = -1 };
48};
49
50template <typename T, typename Tail>
51struct IndexOf<TypeList<T, Tail>, T> {
52    enum { value = 0 };
53};
54
55template <typename Head, typename Tail, typename T>
56struct IndexOf<TypeList<Head, Tail>, T> {
57private:
58    enum { temp = IndexOf<Tail, T>::value };
59public:
60    enum { value = temp == -1 ? -1 : 1 + temp };
61};
62
63}; // namespace TL
64
65// type selection based on a boolean
66template <bool flag, typename T, typename U>
67struct Select {
68    typedef T Result;
69};
70template <typename T, typename U>
71struct Select<false, T, U> {
72    typedef U Result;
73};
74
75// -----------------------------------------------------------------------
76// Type traits
77
78template <typename T>
79class 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
103public:
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