aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/tr1/type_traits
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/tr1/type_traits')
-rw-r--r--libstdc++-v3/include/tr1/type_traits173
1 files changed, 114 insertions, 59 deletions
diff --git a/libstdc++-v3/include/tr1/type_traits b/libstdc++-v3/include/tr1/type_traits
index 0fb5916fc65..55f585f9f4b 100644
--- a/libstdc++-v3/include/tr1/type_traits
+++ b/libstdc++-v3/include/tr1/type_traits
@@ -42,7 +42,7 @@ namespace std
{
namespace tr1
{
- // For use in is_enum, is_abstract and elsewhere.
+ // For use in __conv_helper, is_abstract and elsewhere.
struct __sfinae_types
{
typedef char __one;
@@ -166,47 +166,22 @@ namespace tr1
_DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
is_function<_Tp>::value)
- template<typename _Tp, bool = (is_fundamental<_Tp>::value
- || is_array<_Tp>::value
- || is_pointer<_Tp>::value
- || is_reference<_Tp>::value
- || is_member_pointer<_Tp>::value
- || is_function<_Tp>::value)>
- struct __is_enum_helper
- : public __sfinae_types
- {
- private:
- static __one __test(bool);
- static __one __test(char);
- static __one __test(signed char);
- static __one __test(unsigned char);
-#ifdef _GLIBCXX_USE_WCHAR_T
- static __one __test(wchar_t);
-#endif
- static __one __test(short);
- static __one __test(unsigned short);
- static __one __test(int);
- static __one __test(unsigned int);
- static __one __test(long);
- static __one __test(unsigned long);
- static __one __test(long long);
- static __one __test(unsigned long long);
- static __two __test(...);
-
- struct __convert
- { operator _Tp() const; };
-
- public:
- static const bool __value = sizeof(__test(__convert())) == 1;
- };
-
- template<typename _Tp>
- struct __is_enum_helper<_Tp, true>
- { static const bool __value = false; };
-
template<typename _Tp>
struct is_enum
- : public integral_constant<bool, __is_enum_helper<_Tp>::__value> { };
+ : public integral_constant<bool, !(is_fundamental<_Tp>::value
+ || is_array<_Tp>::value
+ || is_pointer<_Tp>::value
+ || is_reference<_Tp>::value
+ || is_member_pointer<_Tp>::value
+ || is_function<_Tp>::value
+ || __is_union_or_class<_Tp>::value)>
+ { };
+
+ template<typename>
+ struct is_union { };
+
+ template<typename>
+ struct is_class { };
template<typename _Tp, bool = (is_void<_Tp>::value
|| is_reference<_Tp>::value)>
@@ -264,6 +239,26 @@ namespace tr1
(is_member_object_pointer<_Tp>::value
|| is_member_function_pointer<_Tp>::value)>
{ };
+
+ template<typename _Tp>
+ struct __is_union_or_class_helper
+ : public __sfinae_types
+ {
+ private:
+ template<typename _Up>
+ static __one __test(int _Up::*);
+ template<typename>
+ static __two __test(...);
+
+ public:
+ static const bool __value = sizeof(__test<_Tp>(0)) == 1;
+ };
+
+ // Extension.
+ template<typename _Tp>
+ struct __is_union_or_class
+ : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value>
+ { };
/// @brief type properties [4.5.3].
template<typename>
@@ -289,26 +284,21 @@ namespace tr1
remove_all_extents<_Tp>::type>::value)>
{ };
- template<typename>
- struct __is_empty_helper_1
- { };
-
- template<typename _Tp>
- struct __is_empty_helper_2
- : public _Tp { };
-
- // Unfortunately, without compiler support we cannot tell union from
- // class types, and is_empty doesn't work at all with the former.
- template<typename _Tp, bool = (is_fundamental<_Tp>::value
- || is_array<_Tp>::value
- || is_pointer<_Tp>::value
- || is_reference<_Tp>::value
- || is_member_pointer<_Tp>::value
- || is_enum<_Tp>::value
- || is_function<_Tp>::value)>
+ // N.B. Without compiler support we cannot tell union from class types,
+ // and is_empty and is_polymorphic don't work at all with the former.
+ template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
struct __is_empty_helper
- { static const bool __value = (sizeof(__is_empty_helper_1<_Tp>)
- == sizeof(__is_empty_helper_2<_Tp>)); };
+ {
+ private:
+ template<typename>
+ struct __first { };
+ template<typename _Up>
+ struct __second
+ : public _Up { };
+
+ public:
+ static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
+ };
template<typename _Tp>
struct __is_empty_helper<_Tp, true>
@@ -319,6 +309,34 @@ namespace tr1
: public integral_constant<bool, __is_empty_helper<_Tp>::__value>
{ };
+ template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
+ struct __is_polymorphic_helper
+ {
+ private:
+ template<typename _Up>
+ struct __first
+ : public _Up { };
+ template<typename _Up>
+ struct __second
+ : public _Up
+ {
+ virtual void __dummy();
+ virtual ~__second();
+ };
+
+ public:
+ static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
+ };
+
+ template<typename _Tp>
+ struct __is_polymorphic_helper<_Tp, true>
+ { static const bool __value = false; };
+
+ template<typename _Tp>
+ struct is_polymorphic
+ : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value>
+ { };
+
// Exploit the resolution DR core/337.
template<typename _Tp, bool = !is_object<_Tp>::value>
struct __is_abstract_helper
@@ -441,6 +459,43 @@ namespace tr1
struct is_same<_Tp, _Tp>
: public true_type { };
+ // See Daveed Vandevoorde explanation in http://tinyurl.com/502f.
+ // Also see Rani Sharoni in http://tinyurl.com/6jvyq.
+ template<typename _Base, typename _Derived,
+ bool = (!__is_union_or_class<_Base>::value
+ || !__is_union_or_class<_Derived>::value
+ || is_same<_Base, _Derived>::value)>
+ struct __is_base_of_helper
+ : public __sfinae_types
+ {
+ private:
+ typedef typename remove_cv<_Base>::type _NoCv_Base;
+ typedef typename remove_cv<_Derived>::type _NoCv_Derived;
+
+ template<typename _Up>
+ static __one __test(_NoCv_Derived&, _Up);
+ static __two __test(_NoCv_Base&, int);
+
+ struct _Conv
+ {
+ operator _NoCv_Derived&();
+ operator _NoCv_Base&() const;
+ };
+
+ public:
+ static const bool __value = sizeof(__test(_Conv(), 0)) == 1;
+ };
+
+ template<typename _Base, typename _Derived>
+ struct __is_base_of_helper<_Base, _Derived, true>
+ { static const bool __value = is_same<_Base, _Derived>::value; };
+
+ template<typename _Base, typename _Derived>
+ struct is_base_of
+ : public integral_constant<bool,
+ __is_base_of_helper<_Base, _Derived>::__value>
+ { };
+
template<typename _Tp>
struct __is_int_or_cref
{