type_traits.h revision ff21b24c190969c3be879b6c28d16711c779b1eb
1/* -*- c++ -*- */
2/*
3 * Copyright (C) 2009 The Android Open Source Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *  * Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 *  * Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in
13 *    the documentation and/or other materials provided with the
14 *    distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#ifndef ANDROID_ASTL_TYPE_TRAITS_H__
31#define ANDROID_ASTL_TYPE_TRAITS_H__
32
33// GNU C++ compiler?
34#ifndef __GNUG__
35#error "__GNUG__ is not defined"
36#endif
37
38#ifdef _T
39#error "_T is defined"
40#endif
41
42// In this files is a set of templates used to instrospect some
43// template arguments properties.
44//
45// For instance to provide a specialized implementation of a template
46// function foo<_T> when its template argument is a pointer type:
47//
48// template<typename _T> void foo(_T val) {  // template function
49//   const bool is_pointer = is_pointer<_T>::value;
50//   __foo<is_pointer>::foo(val);              // concrete impl
51// }
52//
53// template<bool> struct __foo {
54//   template<typename _T> static void foo(_T val) {
55//     .... default implementation ...
56//   }
57// }
58//
59// Specialization of the above when the bool parameter is true (i.e is
60// a pointer)
61//
62// template<> struct __foo<true> {
63//   template<typename _T> static void foo(_T val) {
64//     .... pointer specific implementation ...
65//   }
66// }
67//
68
69namespace std {
70
71template<typename _T, _T _value>
72struct integral_constant
73{
74    static const _T                       value = _value;
75    typedef _T                            value_type;
76    typedef integral_constant<_T, _value> type;
77};
78
79// typedef for true and false types
80typedef integral_constant<bool, true>  true_type;
81typedef integral_constant<bool, false> false_type;
82
83
84// is_integral
85template<typename> struct is_integral : public false_type { };
86
87#define DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(_Type)                 \
88    template<> struct is_integral<_Type>: public true_type { }; \
89    template<> struct is_integral<_Type const>: public true_type { }; \
90    template<> struct is_integral<_Type volatile>: public true_type { }; \
91    template<> struct is_integral<_Type const volatile>: public true_type { };
92
93DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(bool)
94DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(char)
95DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(signed char)
96DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned char)
97DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(wchar_t)
98DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(short)
99DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned short)
100DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(int)
101DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned int)
102DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(long)
103DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned long)
104DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(long long)
105DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned long long)
106#undef DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE
107
108// is_floating_point
109template<typename> struct is_floating_point : public false_type { };
110#define DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(_Type)           \
111    template<> struct is_floating_point<_Type>: public true_type { }; \
112    template<> struct is_floating_point<_Type const>: public true_type { }; \
113    template<> struct is_floating_point<_Type volatile>: public true_type { }; \
114    template<> struct is_floating_point<_Type const volatile>: public true_type { };
115
116DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(float)
117DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(double)
118DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(long double)
119#undef DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE
120
121// is_pointer
122template<typename> struct is_pointer : public false_type { };
123
124template<typename _T>
125struct is_pointer<_T*>: public true_type { };
126
127template<typename _T>
128struct is_pointer<_T* const>: public true_type { };
129
130template<typename _T>
131struct is_pointer<_T* volatile>: public true_type { };
132
133template<typename _T>
134struct is_pointer<_T* const volatile>: public true_type { };
135
136
137// is_arithmetic
138template<typename _T>
139struct is_arithmetic : public integral_constant<bool, (is_integral<_T>::value || is_floating_point<_T>::value)> { };
140
141// is_scalar
142// TODO: Add is_enum and is_member_pointer when gcc > 4.1.3
143template<typename _T>
144struct is_scalar
145        : public integral_constant<bool, (is_arithmetic<_T>::value || is_pointer<_T>::value)> { };
146
147// Substitution Failure Is Not An Error used in is_pod.
148struct sfinae_types
149{
150    typedef char one;
151    typedef struct { char arr[2]; } two;
152};
153
154// Only classes will match the first declaration (pointer to member).
155// TODO: newer version of gcc have these is_class built in.
156template<typename _T>  sfinae_types::one test_pod_type(int _T::*);
157template<typename _T>  sfinae_types::two& test_pod_type(...);
158
159template<typename _T>
160struct is_pod: public integral_constant<bool, sizeof(test_pod_type<_T>(0)) != sizeof(sfinae_types::one)> { };
161
162template<typename _T>
163struct is_class: public integral_constant<bool, sizeof(test_pod_type<_T>(0)) == sizeof(sfinae_types::one)> { };
164
165}  // namespace std
166
167#endif  // ANDROID_ASTL_TYPE_TRAITS_H__
168