diff options
Diffstat (limited to 'libstdc++-v3/include/tr1/type_traits')
-rw-r--r-- | libstdc++-v3/include/tr1/type_traits | 173 |
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 { |