/* -*- c++ -*- */ /* * Copyright (C) 2009 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef ANDROID_ASTL_TYPE_TRAITS_H__ #define ANDROID_ASTL_TYPE_TRAITS_H__ // GNU C++ compiler? #ifndef __GNUG__ #error "__GNUG__ is not defined" #endif #ifdef _T #error "_T is defined" #endif // In this files is a set of templates used to instrospect some // template arguments properties. // // For instance to provide a specialized implementation of a template // function foo<_T> when its template argument is a pointer type: // // template void foo(_T val) { // template function // const bool is_pointer = is_pointer<_T>::value; // __foo::foo(val); // concrete impl // } // // template struct __foo { // template static void foo(_T val) { // .... default implementation ... // } // } // // Specialization of the above when the bool parameter is true (i.e is // a pointer) // // template<> struct __foo { // template static void foo(_T val) { // .... pointer specific implementation ... // } // } // namespace std { template struct integral_constant { static const _T value = _value; typedef _T value_type; typedef integral_constant<_T, _value> type; }; // typedef for true and false types typedef integral_constant true_type; typedef integral_constant false_type; // is_integral template struct is_integral : public false_type { }; #define DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(_Type) \ template<> struct is_integral<_Type>: public true_type { }; \ template<> struct is_integral<_Type const>: public true_type { }; \ template<> struct is_integral<_Type volatile>: public true_type { }; \ template<> struct is_integral<_Type const volatile>: public true_type { }; DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(bool) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(char) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(signed char) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned char) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(wchar_t) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(short) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned short) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(int) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned int) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(long) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned long) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(long long) DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE(unsigned long long) #undef DEFINE_IS_INTEGRAL_TO_TRUE_TYPE_FOR_TYPE // is_floating_point template struct is_floating_point : public false_type { }; #define DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(_Type) \ template<> struct is_floating_point<_Type>: public true_type { }; \ template<> struct is_floating_point<_Type const>: public true_type { }; \ template<> struct is_floating_point<_Type volatile>: public true_type { }; \ template<> struct is_floating_point<_Type const volatile>: public true_type { }; DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(float) DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(double) DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE(long double) #undef DEFINE_IS_FLOATING_POINT_TO_TRUE_TYPE_FOR_TYPE // is_pointer template struct is_pointer : public false_type { }; template struct is_pointer<_T*>: public true_type { }; template struct is_pointer<_T* const>: public true_type { }; template struct is_pointer<_T* volatile>: public true_type { }; template struct is_pointer<_T* const volatile>: public true_type { }; // is_arithmetic template struct is_arithmetic : public integral_constant::value || is_floating_point<_T>::value)> { }; // is_scalar // TODO: Add is_enum and is_member_pointer when gcc > 4.1.3 template struct is_scalar : public integral_constant::value || is_pointer<_T>::value)> { }; // Substitution Failure Is Not An Error used in is_pod. struct sfinae_types { typedef char one; typedef struct { char arr[2]; } two; }; // Only classes will match the first declaration (pointer to member). // TODO: newer version of gcc have these is_class built in. template sfinae_types::one test_pod_type(int _T::*); template sfinae_types::two& test_pod_type(...); template struct is_pod: public integral_constant(0)) != sizeof(sfinae_types::one)> { }; template struct is_class: public integral_constant(0)) == sizeof(sfinae_types::one)> { }; } // namespace std #endif // ANDROID_ASTL_TYPE_TRAITS_H__