• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
69 namespace std {
70 
71 template<typename _T, _T _value>
72 struct 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
80 typedef integral_constant<bool, true>  true_type;
81 typedef integral_constant<bool, false> false_type;
82 
83 
84 // is_integral
85 template<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 
93 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(bool)
94 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(char)
95 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(signed char)
96 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned char)
97 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(wchar_t)
98 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(short)
99 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned short)
100 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(int)
101 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned int)
102 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(long)
103 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned long)
104 DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(long long)
105 DEFINE_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
109 template<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 
116 DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(float)
117 DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(double)
118 DEFINE_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
122 template<typename> struct is_pointer : public false_type { };
123 
124 template<typename _T>
125 struct is_pointer<_T*>: public true_type { };
126 
127 template<typename _T>
128 struct is_pointer<_T* const>: public true_type { };
129 
130 template<typename _T>
131 struct is_pointer<_T* volatile>: public true_type { };
132 
133 template<typename _T>
134 struct is_pointer<_T* const volatile>: public true_type { };
135 
136 
137 // is_arithmetic
138 template<typename _T>
139 struct 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
143 template<typename _T>
144 struct 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.
148 struct 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.
156 template<typename _T>  sfinae_types::one test_pod_type(int _T::*);
157 template<typename _T>  sfinae_types::two& test_pod_type(...);
158 
159 template<typename _T>
160 struct is_pod: public integral_constant<bool, sizeof(test_pod_type<_T>(0)) != sizeof(sfinae_types::one)> { };
161 
162 template<typename _T>
163 struct 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