Home | History | Annotate | Download | only in ext
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005-2013 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the terms
      7 // of the GNU General Public License as published by the Free Software
      8 // Foundation; either version 3, or (at your option) any later
      9 // version.
     10 
     11 // This library is distributed in the hope that it will be useful, but
     12 // WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 // General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file ext/type_traits.h
     26  *  This file is a GNU extension to the Standard C++ Library.
     27  */
     28 
     29 #ifndef _EXT_TYPE_TRAITS
     30 #define _EXT_TYPE_TRAITS 1
     31 
     32 #pragma GCC system_header
     33 
     34 #include <bits/c++config.h>
     35 #include <bits/cpp_type_traits.h>
     36 
     37 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
     38 {
     39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     40 
     41   // Define a nested type if some predicate holds.
     42   template<bool, typename>
     43     struct __enable_if
     44     { };
     45 
     46   template<typename _Tp>
     47     struct __enable_if<true, _Tp>
     48     { typedef _Tp __type; };
     49 
     50 
     51   // Conditional expression for types. If true, first, if false, second.
     52   template<bool _Cond, typename _Iftrue, typename _Iffalse>
     53     struct __conditional_type
     54     { typedef _Iftrue __type; };
     55 
     56   template<typename _Iftrue, typename _Iffalse>
     57     struct __conditional_type<false, _Iftrue, _Iffalse>
     58     { typedef _Iffalse __type; };
     59 
     60 
     61   // Given an integral builtin type, return the corresponding unsigned type.
     62   template<typename _Tp>
     63     struct __add_unsigned
     64     {
     65     private:
     66       typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
     67 
     68     public:
     69       typedef typename __if_type::__type __type;
     70     };
     71 
     72   template<>
     73     struct __add_unsigned<char>
     74     { typedef unsigned char __type; };
     75 
     76   template<>
     77     struct __add_unsigned<signed char>
     78     { typedef unsigned char __type; };
     79 
     80   template<>
     81     struct __add_unsigned<short>
     82     { typedef unsigned short __type; };
     83 
     84   template<>
     85     struct __add_unsigned<int>
     86     { typedef unsigned int __type; };
     87 
     88   template<>
     89     struct __add_unsigned<long>
     90     { typedef unsigned long __type; };
     91 
     92   template<>
     93     struct __add_unsigned<long long>
     94     { typedef unsigned long long __type; };
     95 
     96   // Declare but don't define.
     97   template<>
     98     struct __add_unsigned<bool>;
     99 
    100   template<>
    101     struct __add_unsigned<wchar_t>;
    102 
    103 
    104   // Given an integral builtin type, return the corresponding signed type.
    105   template<typename _Tp>
    106     struct __remove_unsigned
    107     {
    108     private:
    109       typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
    110 
    111     public:
    112       typedef typename __if_type::__type __type;
    113     };
    114 
    115   template<>
    116     struct __remove_unsigned<char>
    117     { typedef signed char __type; };
    118 
    119   template<>
    120     struct __remove_unsigned<unsigned char>
    121     { typedef signed char __type; };
    122 
    123   template<>
    124     struct __remove_unsigned<unsigned short>
    125     { typedef short __type; };
    126 
    127   template<>
    128     struct __remove_unsigned<unsigned int>
    129     { typedef int __type; };
    130 
    131   template<>
    132     struct __remove_unsigned<unsigned long>
    133     { typedef long __type; };
    134 
    135   template<>
    136     struct __remove_unsigned<unsigned long long>
    137     { typedef long long __type; };
    138 
    139   // Declare but don't define.
    140   template<>
    141     struct __remove_unsigned<bool>;
    142 
    143   template<>
    144     struct __remove_unsigned<wchar_t>;
    145 
    146 
    147   // For use in string and vstring.
    148   template<typename _Type>
    149     inline bool
    150     __is_null_pointer(_Type* __ptr)
    151     { return __ptr == 0; }
    152 
    153   template<typename _Type>
    154     inline bool
    155     __is_null_pointer(_Type)
    156     { return false; }
    157 
    158 
    159   // For complex and cmath
    160   template<typename _Tp, bool = std::__is_integer<_Tp>::__value>
    161     struct __promote
    162     { typedef double __type; };
    163 
    164   // No nested __type member for non-integer non-floating point types,
    165   // allows this type to be used for SFINAE to constrain overloads in
    166   // <cmath> and <complex> to only the intended types.
    167   template<typename _Tp>
    168     struct __promote<_Tp, false>
    169     { };
    170 
    171   template<>
    172     struct __promote<long double>
    173     { typedef long double __type; };
    174 
    175   template<>
    176     struct __promote<double>
    177     { typedef double __type; };
    178 
    179   template<>
    180     struct __promote<float>
    181     { typedef float __type; };
    182 
    183   template<typename _Tp, typename _Up,
    184            typename _Tp2 = typename __promote<_Tp>::__type,
    185            typename _Up2 = typename __promote<_Up>::__type>
    186     struct __promote_2
    187     {
    188       typedef __typeof__(_Tp2() + _Up2()) __type;
    189     };
    190 
    191   template<typename _Tp, typename _Up, typename _Vp,
    192            typename _Tp2 = typename __promote<_Tp>::__type,
    193            typename _Up2 = typename __promote<_Up>::__type,
    194            typename _Vp2 = typename __promote<_Vp>::__type>
    195     struct __promote_3
    196     {
    197       typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type;
    198     };
    199 
    200   template<typename _Tp, typename _Up, typename _Vp, typename _Wp,
    201            typename _Tp2 = typename __promote<_Tp>::__type,
    202            typename _Up2 = typename __promote<_Up>::__type,
    203            typename _Vp2 = typename __promote<_Vp>::__type,
    204            typename _Wp2 = typename __promote<_Wp>::__type>
    205     struct __promote_4
    206     {
    207       typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type;
    208     };
    209 
    210 _GLIBCXX_END_NAMESPACE_VERSION
    211 } // namespace
    212 
    213 #endif
    214