This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] tr1/type_traits: __is_union_or_class and more
- From: Paolo Carlini <pcarlini at suse dot de>
- To: "'gcc-patches at gcc dot gnu dot org'" <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 25 Feb 2005 19:22:51 +0100
- Subject: [v3] tr1/type_traits: __is_union_or_class and more
Hi,
the below adds the __is_union_or_class extension (the individual
is_union and is_class are not useful without compiler support)
and uses it to implement is_enum and is_empty.
Tested x86-linux.
Paolo.
////////////
2005-02-25 Paolo Carlini <pcarlini@suse.de>
* include/tr1/type_traits: Add the trivial is_union and is_class;
add the __is_union_or_class extension.
(is_enum, is_empty): Use the latter.
* include/tr1/type_traits_fwd.h: Add __is_union_or_class.
* testsuite/testsuite_tr1.h: Add UnionType; trivial formatting
fixes.
* testsuite/tr1/4_metaprogramming/composite_type_traits/
is_union_or_class/is_union_or_class.cc: New.
* testsuite/tr1/4_metaprogramming/composite_type_traits/
is_union_or_class/typedefs.cc: Likewise.
diff -prN libstdc++-v3-orig/include/tr1/type_traits libstdc++-v3/include/tr1/type_traits
*** libstdc++-v3-orig/include/tr1/type_traits Wed Feb 23 18:23:43 2005
--- libstdc++-v3/include/tr1/type_traits Fri Feb 25 18:35:37 2005
*************** namespace tr1
*** 166,212 ****
_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> { };
template<typename _Tp, bool = (is_void<_Tp>::value
|| is_reference<_Tp>::value)>
--- 166,187 ----
_DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
is_function<_Tp>::value)
template<typename _Tp>
struct is_enum
! : 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)>
*************** namespace tr1
*** 264,269 ****
--- 239,264 ----
(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>
*************** namespace tr1
*** 289,314 ****
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)>
struct __is_empty_helper
! { static const bool __value = (sizeof(__is_empty_helper_1<_Tp>)
! == sizeof(__is_empty_helper_2<_Tp>)); };
template<typename _Tp>
struct __is_empty_helper<_Tp, true>
--- 284,304 ----
remove_all_extents<_Tp>::type>::value)>
{ };
! // N.B. 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_union_or_class<_Tp>::value>
struct __is_empty_helper
! {
! private:
! template<typename>
! struct __ebo_1 { };
! template<typename _Up>
! struct __ebo_2
! : public _Up { };
!
! public:
! static const bool __value = sizeof(__ebo_1<_Tp>) == sizeof(__ebo_2<_Tp>);
! };
template<typename _Tp>
struct __is_empty_helper<_Tp, true>
diff -prN libstdc++-v3-orig/include/tr1/type_traits_fwd.h libstdc++-v3/include/tr1/type_traits_fwd.h
*** libstdc++-v3-orig/include/tr1/type_traits_fwd.h Tue Feb 22 18:07:07 2005
--- libstdc++-v3/include/tr1/type_traits_fwd.h Fri Feb 25 18:32:04 2005
*************** namespace tr1
*** 103,108 ****
--- 103,112 ----
template<typename _Tp>
struct is_member_pointer;
+
+ // Extension.
+ template<typename _Tp>
+ struct __is_union_or_class;
/// @brief type properties [4.5.3].
template<typename _Tp>
diff -prN libstdc++-v3-orig/testsuite/testsuite_tr1.h libstdc++-v3/testsuite/testsuite_tr1.h
*** libstdc++-v3-orig/testsuite/testsuite_tr1.h Thu Feb 24 02:16:07 2005
--- libstdc++-v3/testsuite/testsuite_tr1.h Fri Feb 25 18:22:34 2005
*************** namespace __gnu_test
*** 123,189 ****
class AbstractClass
{ virtual void rotate(int) = 0; };
- int truncate_float(float x) { return (int)x; }
- long truncate_double(double x) { return (long)x; }
! struct do_truncate_float_t
! {
! do_truncate_float_t()
! {
! ++live_objects;
! }
!
! do_truncate_float_t(const do_truncate_float_t&)
! {
! ++live_objects;
! }
!
! ~do_truncate_float_t()
! {
! --live_objects;
! }
!
! int operator()(float x) { return (int)x; }
!
! static int live_objects;
! };
!
! int do_truncate_float_t::live_objects = 0;
! struct do_truncate_double_t
! {
! do_truncate_double_t()
! {
++live_objects;
! }
!
! do_truncate_double_t(const do_truncate_double_t&)
! {
! ++live_objects;
! }
!
! ~do_truncate_double_t()
! {
! --live_objects;
! }
!
! long operator()(double x) { return (long)x; }
!
! static int live_objects;
! };
!
! int do_truncate_double_t::live_objects = 0;
!
! struct X
! {
! int bar;
! int foo() { return 1; }
! int foo_c() const { return 2; }
! int foo_v() volatile { return 3; }
! int foo_cv() const volatile { return 4; }
! };
}; // namespace __gnu_test
#endif // _GLIBCXX_TESTSUITE_TR1_H
--- 123,191 ----
class AbstractClass
{ virtual void rotate(int) = 0; };
+ union UnionType { };
! int truncate_float(float x) { return (int)x; }
! long truncate_double(double x) { return (long)x; }
! struct do_truncate_float_t
! {
! do_truncate_float_t()
! {
! ++live_objects;
! }
!
! do_truncate_float_t(const do_truncate_float_t&)
! {
! ++live_objects;
! }
!
! ~do_truncate_float_t()
! {
! --live_objects;
! }
!
! int operator()(float x) { return (int)x; }
!
! static int live_objects;
! };
!
! int do_truncate_float_t::live_objects = 0;
!
! struct do_truncate_double_t
! {
! do_truncate_double_t()
! {
++live_objects;
! }
! do_truncate_double_t(const do_truncate_double_t&)
! {
! ++live_objects;
! }
!
! ~do_truncate_double_t()
! {
! --live_objects;
! }
!
! long operator()(double x) { return (long)x; }
!
! static int live_objects;
! };
!
! int do_truncate_double_t::live_objects = 0;
!
! struct X
! {
! int bar;
!
! int foo() { return 1; }
! int foo_c() const { return 2; }
! int foo_v() volatile { return 3; }
! int foo_cv() const volatile { return 4; }
! };
}; // namespace __gnu_test
#endif // _GLIBCXX_TESTSUITE_TR1_H
diff -prN libstdc++-v3-orig/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/is_union_or_class.cc libstdc++-v3/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/is_union_or_class.cc
*** libstdc++-v3-orig/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/is_union_or_class.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/is_union_or_class.cc Fri Feb 25 19:02:05 2005
***************
*** 0 ****
--- 1,60 ----
+ // 2005-02-25 Paolo Carlini <pcarlini@suse.de>
+ //
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ //
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // 4.5.2 Composite type traits
+
+ #include <tr1/type_traits>
+ #include <testsuite_hooks.h>
+ #include <testsuite_tr1.h>
+
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+ using std::tr1::__is_union_or_class;
+ using namespace __gnu_test;
+
+ // Positive tests.
+ VERIFY( (test_category<__is_union_or_class, UnionType>(true)) );
+ VERIFY( (test_category<__is_union_or_class, ClassType>(true)) );
+ VERIFY( (test_category<__is_union_or_class, DerivedType>(true)) );
+ VERIFY( (test_category<__is_union_or_class, ConvType>(true)) );
+ VERIFY( (test_category<__is_union_or_class, AbstractClass>(true)) );
+
+ // Negative tests.
+ VERIFY( (test_category<__is_union_or_class, void>(false)) );
+ VERIFY( (test_category<__is_union_or_class, int>(false)) );
+ VERIFY( (test_category<__is_union_or_class, float>(false)) );
+ VERIFY( (test_category<__is_union_or_class, int[2]>(false)) );
+ VERIFY( (test_category<__is_union_or_class, int*>(false)) );
+ VERIFY( (test_category<__is_union_or_class, int(*)(int)>(false)) );
+ VERIFY( (test_category<__is_union_or_class, float&>(false)) );
+ VERIFY( (test_category<__is_union_or_class, float(&)(float)>(false)) );
+ VERIFY( (test_category<__is_union_or_class, int (ClassType::*)>(false)) );
+ VERIFY( (test_category<__is_union_or_class,
+ int (ClassType::*) (int)>(false)) );
+ VERIFY( (test_category<__is_union_or_class, int (int)>(false)) );
+ VERIFY( (test_category<__is_union_or_class, EnumType>(false)) );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/typedefs.cc libstdc++-v3/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/typedefs.cc
*** libstdc++-v3-orig/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/typedefs.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/tr1/4_metaprogramming/composite_type_traits/is_union_or_class/typedefs.cc Fri Feb 25 18:17:22 2005
***************
*** 0 ****
--- 1,36 ----
+ // 2005-02-25 Paolo Carlini <pcarlini@suse.de>
+ //
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ //
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ //
+ // NB: This file is for testing tr1/type_traits with NO OTHER INCLUDES.
+
+ #include <tr1/type_traits>
+
+ // { dg-do compile }
+
+ void test01()
+ {
+ // Check for required typedefs
+ typedef std::tr1::__is_union_or_class<int> test_type;
+ typedef test_type::value_type value_type;
+ typedef test_type::type type;
+ typedef test_type::type::value_type type_value_type;
+ typedef test_type::type::type type_type;
+ }