1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
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 2, or (at your option)
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file tr1/type_traits
31 * This is a TR1 C++ Library header.
34 #ifndef _GLIBCXX_TR1_TYPE_TRAITS
35 #define _GLIBCXX_TR1_TYPE_TRAITS 1
37 #pragma GCC system_header
39 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
40 # error TR1 header cannot be included from C++0x header
45 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
46 # include <tr1_impl/type_traits>
48 # define _GLIBCXX_INCLUDE_AS_TR1
49 # define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
50 # define _GLIBCXX_END_NAMESPACE_TR1 }
51 # define _GLIBCXX_TR1 tr1::
52 # include <tr1_impl/type_traits>
54 # undef _GLIBCXX_END_NAMESPACE_TR1
55 # undef _GLIBCXX_BEGIN_NAMESPACE_TR1
56 # undef _GLIBCXX_INCLUDE_AS_TR1
63 #define _DEFINE_SPEC_BODY(_Value) \
64 : public integral_constant<bool, _Value> { };
66 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \
69 _DEFINE_SPEC_BODY(_Value)
71 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
72 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \
73 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \
74 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \
75 _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
79 : public false_type { };
81 template<typename _Tp>
82 struct is_reference<_Tp&>
83 : public true_type { };
85 template<typename _Tp>
87 : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
90 template<typename _Tp>
91 struct has_trivial_constructor
92 : public integral_constant<bool, is_pod<_Tp>::value>
95 template<typename _Tp>
96 struct has_trivial_copy
97 : public integral_constant<bool, is_pod<_Tp>::value>
100 template<typename _Tp>
101 struct has_trivial_assign
102 : public integral_constant<bool, is_pod<_Tp>::value>
105 template<typename _Tp>
106 struct has_trivial_destructor
107 : public integral_constant<bool, is_pod<_Tp>::value>
110 template<typename _Tp>
111 struct has_nothrow_constructor
112 : public integral_constant<bool, is_pod<_Tp>::value>
115 template<typename _Tp>
116 struct has_nothrow_copy
117 : public integral_constant<bool, is_pod<_Tp>::value>
120 template<typename _Tp>
121 struct has_nothrow_assign
122 : public integral_constant<bool, is_pod<_Tp>::value>
127 : public false_type { };
128 _DEFINE_SPEC(0, is_signed, signed char, true)
129 _DEFINE_SPEC(0, is_signed, short, true)
130 _DEFINE_SPEC(0, is_signed, int, true)
131 _DEFINE_SPEC(0, is_signed, long, true)
132 _DEFINE_SPEC(0, is_signed, long long, true)
136 : public false_type { };
137 _DEFINE_SPEC(0, is_unsigned, unsigned char, true)
138 _DEFINE_SPEC(0, is_unsigned, unsigned short, true)
139 _DEFINE_SPEC(0, is_unsigned, unsigned int, true)
140 _DEFINE_SPEC(0, is_unsigned, unsigned long, true)
141 _DEFINE_SPEC(0, is_unsigned, unsigned long long, true)
143 template<typename _Base, typename _Derived>
144 struct __is_base_of_helper
146 typedef typename remove_cv<_Base>::type _NoCv_Base;
147 typedef typename remove_cv<_Derived>::type _NoCv_Derived;
148 static const bool __value = (is_same<_Base, _Derived>::value
149 || (__is_base_of(_Base, _Derived)
150 && !is_same<_NoCv_Base,
151 _NoCv_Derived>::value));
154 template<typename _Base, typename _Derived>
156 : public integral_constant<bool,
157 __is_base_of_helper<_Base, _Derived>::__value>
160 template<typename _From, typename _To>
161 struct __is_convertible_simple
162 : public __sfinae_types
165 static __one __test(_To);
166 static __two __test(...);
167 static _From __makeFrom();
170 static const bool __value = sizeof(__test(__makeFrom())) == 1;
173 template<typename _Tp>
174 struct add_reference;
176 template<typename _Tp>
177 struct __is_int_or_cref
179 typedef typename remove_reference<_Tp>::type __rr_Tp;
180 static const bool __value = (is_integral<_Tp>::value
181 || (is_integral<__rr_Tp>::value
182 && is_const<__rr_Tp>::value
183 && !is_volatile<__rr_Tp>::value));
186 template<typename _From, typename _To,
187 bool = (is_void<_From>::value || is_void<_To>::value
188 || is_function<_To>::value || is_array<_To>::value
189 // This special case is here only to avoid warnings.
190 || (is_floating_point<typename
191 remove_reference<_From>::type>::value
192 && __is_int_or_cref<_To>::__value))>
193 struct __is_convertible_helper
195 // "An imaginary lvalue of type From...".
196 static const bool __value = (__is_convertible_simple<typename
197 add_reference<_From>::type, _To>::__value);
200 template<typename _From, typename _To>
201 struct __is_convertible_helper<_From, _To, true>
202 { static const bool __value = (is_void<_To>::value
203 || (__is_int_or_cref<_To>::__value
204 && !is_void<_From>::value)); };
206 template<typename _From, typename _To>
207 struct is_convertible
208 : public integral_constant<bool,
209 __is_convertible_helper<_From, _To>::__value>
212 /// @brief reference modifications [4.7.2].
213 template<typename _Tp>
214 struct remove_reference
215 { typedef _Tp type; };
217 template<typename _Tp>
218 struct remove_reference<_Tp&>
219 { typedef _Tp type; };
221 // NB: Careful with reference to void.
222 template<typename _Tp, bool = (is_void<_Tp>::value
223 || is_reference<_Tp>::value)>
224 struct __add_reference_helper
225 { typedef _Tp& type; };
227 template<typename _Tp>
228 struct __add_reference_helper<_Tp, true>
229 { typedef _Tp type; };
231 template<typename _Tp>
233 : public __add_reference_helper<_Tp>
236 /// @brief other transformations [4.8].
237 template<std::size_t _Len, std::size_t _Align>
238 struct aligned_storage
242 unsigned char __data[_Len];
243 struct __attribute__((__aligned__((_Align)))) { } __align;
247 #undef _DEFINE_SPEC_0_HELPER
249 #undef _DEFINE_SPEC_BODY
253 #endif // _GLIBCXX_TR1_TYPE_TRAITS