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