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