This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]