1// TR1 type_traits -*- C++ -*-
2
3// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU 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 tr1/type_traits
26 *  This is a TR1 C++ Library header. 
27 */
28
29#ifndef _GLIBCXX_TR1_TYPE_TRAITS
30#define _GLIBCXX_TR1_TYPE_TRAITS 1
31
32#pragma GCC system_header
33
34#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
35#  error TR1 header cannot be included from C++0x header
36#endif
37
38#include <cstddef>
39
40#if defined(_GLIBCXX_INCLUDE_AS_TR1)
41#  include <tr1_impl/type_traits>
42#else
43#  define _GLIBCXX_INCLUDE_AS_TR1
44#  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
45#  define _GLIBCXX_END_NAMESPACE_TR1 }
46#  define _GLIBCXX_TR1 tr1::
47#  include <tr1_impl/type_traits>
48#  undef _GLIBCXX_TR1
49#  undef _GLIBCXX_END_NAMESPACE_TR1
50#  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
51#  undef _GLIBCXX_INCLUDE_AS_TR1
52#endif
53
54namespace std
55{
56namespace tr1
57{
58#define _DEFINE_SPEC(_Trait, _Type)    \
59  template<>                           \
60    struct _Trait<_Type>	       \
61    : public true_type { };
62
63  template<typename>
64    struct is_reference
65    : public false_type { };
66
67  template<typename _Tp>
68    struct is_reference<_Tp&>
69    : public true_type { };
70
71  template<typename _Tp>
72    struct is_pod
73    : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
74    { };
75
76  template<typename _Tp>
77    struct has_trivial_constructor
78    : public integral_constant<bool, is_pod<_Tp>::value>
79    { };
80
81  template<typename _Tp>
82    struct has_trivial_copy
83    : public integral_constant<bool, is_pod<_Tp>::value>
84    { };
85
86  template<typename _Tp>
87    struct has_trivial_assign
88    : public integral_constant<bool, is_pod<_Tp>::value>
89    { };
90
91  template<typename _Tp>
92    struct has_trivial_destructor
93    : public integral_constant<bool, is_pod<_Tp>::value>
94    { };
95
96  template<typename _Tp>
97    struct has_nothrow_constructor
98    : public integral_constant<bool, is_pod<_Tp>::value>
99    { };
100
101  template<typename _Tp>
102    struct has_nothrow_copy
103    : public integral_constant<bool, is_pod<_Tp>::value>
104    { };
105
106  template<typename _Tp>
107    struct has_nothrow_assign
108    : public integral_constant<bool, is_pod<_Tp>::value>
109    { };
110
111  template<typename>
112    struct __is_signed_helper
113    : public false_type { };
114  _DEFINE_SPEC(__is_signed_helper, signed char)
115  _DEFINE_SPEC(__is_signed_helper, short)
116  _DEFINE_SPEC(__is_signed_helper, int)
117  _DEFINE_SPEC(__is_signed_helper, long)
118  _DEFINE_SPEC(__is_signed_helper, long long)
119
120  template<typename _Tp>
121    struct is_signed
122    : public integral_constant<bool, (__is_signed_helper<typename
123				      remove_cv<_Tp>::type>::value)>
124    { };
125
126  template<typename>
127    struct __is_unsigned_helper
128    : public false_type { };
129  _DEFINE_SPEC(__is_unsigned_helper, unsigned char)
130  _DEFINE_SPEC(__is_unsigned_helper, unsigned short)
131  _DEFINE_SPEC(__is_unsigned_helper, unsigned int)
132  _DEFINE_SPEC(__is_unsigned_helper, unsigned long)
133  _DEFINE_SPEC(__is_unsigned_helper, unsigned long long)
134
135  template<typename _Tp>
136    struct is_unsigned
137    : public integral_constant<bool, (__is_unsigned_helper<typename
138				      remove_cv<_Tp>::type>::value)>
139    { };
140
141  template<typename _Base, typename _Derived>
142    struct __is_base_of_helper
143    {
144      typedef typename remove_cv<_Base>::type    _NoCv_Base;
145      typedef typename remove_cv<_Derived>::type _NoCv_Derived;
146      static const bool __value = (is_same<_Base, _Derived>::value
147				   || (__is_base_of(_Base, _Derived)
148				       && !is_same<_NoCv_Base,
149				                   _NoCv_Derived>::value));
150    };
151 
152  template<typename _Base, typename _Derived>
153    struct is_base_of
154    : public integral_constant<bool,
155			       __is_base_of_helper<_Base, _Derived>::__value>
156    { };
157
158  template<typename _From, typename _To>
159    struct __is_convertible_simple
160    : public __sfinae_types
161    {
162    private:
163      static __one __test(_To);
164      static __two __test(...);
165      static _From __makeFrom();
166    
167    public:
168      static const bool __value = sizeof(__test(__makeFrom())) == 1;
169    };
170
171  template<typename _Tp>
172    struct add_reference;
173
174  template<typename _Tp>
175    struct __is_int_or_cref
176    {
177      typedef typename remove_reference<_Tp>::type __rr_Tp;
178      static const bool __value = (is_integral<_Tp>::value
179				   || (is_integral<__rr_Tp>::value
180				       && is_const<__rr_Tp>::value
181				       && !is_volatile<__rr_Tp>::value));
182    };
183
184  template<typename _From, typename _To,
185	   bool = (is_void<_From>::value || is_void<_To>::value
186		   || is_function<_To>::value || is_array<_To>::value
187		   // This special case is here only to avoid warnings.	
188		   || (is_floating_point<typename
189		       remove_reference<_From>::type>::value
190		       && __is_int_or_cref<_To>::__value))>
191    struct __is_convertible_helper
192    {
193      // "An imaginary lvalue of type From...".
194      static const bool __value = (__is_convertible_simple<typename
195				   add_reference<_From>::type, _To>::__value);
196    };
197
198  template<typename _From, typename _To>
199    struct __is_convertible_helper<_From, _To, true>
200    { static const bool __value = (is_void<_To>::value
201				   || (__is_int_or_cref<_To>::__value
202				       && !is_void<_From>::value)); };
203
204  template<typename _From, typename _To>
205    struct is_convertible
206    : public integral_constant<bool,
207			       __is_convertible_helper<_From, _To>::__value>
208    { };
209
210  // reference modifications [4.7.2].
211  template<typename _Tp>
212    struct remove_reference
213    { typedef _Tp     type; };
214
215  template<typename _Tp>
216    struct remove_reference<_Tp&>
217    { typedef _Tp     type; };
218
219  // NB: Careful with reference to void.
220  template<typename _Tp, bool = (is_void<_Tp>::value
221				 || is_reference<_Tp>::value)>
222    struct __add_reference_helper
223    { typedef _Tp&    type; };
224
225  template<typename _Tp>
226    struct __add_reference_helper<_Tp, true>
227    { typedef _Tp     type; };
228
229  template<typename _Tp>
230    struct add_reference
231    : public __add_reference_helper<_Tp>
232    { };
233
234  // other transformations [4.8].
235  template<std::size_t _Len, std::size_t _Align>
236    struct aligned_storage
237    { 
238      union type
239      {
240	unsigned char __data[_Len];
241	struct __attribute__((__aligned__((_Align)))) { } __align; 
242      };
243    };
244
245#undef _DEFINE_SPEC
246}
247}
248
249#endif // _GLIBCXX_TR1_TYPE_TRAITS
250