Home | History | Annotate | Download | only in include
      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