[multiple changes]
authorPaolo Carlini <paolo@gcc.gnu.org>
Sat, 30 Apr 2011 19:40:06 +0000 (19:40 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sat, 30 Apr 2011 19:40:06 +0000 (19:40 +0000)
2011-04-30  Daniel Krugler  <daniel.kruegler@googlemail.com>

* include/std/type_traits (__is_default_constructible_atom,
__is_default_constructible_safe<, true>,
__is_direct_constructible_new_safe,
__is_base_to_derived_ref<,, true>, __is_lvalue_to_rvalue_ref<,, true>,
__is_direct_constructible_ref_cast, __is_direct_constructible,
__is_nary_constructible): Simplify; add comments throughout.

2011-04-30  Paolo Carlini  <paolo.carlini@oracle.com>

* testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
Adjust dg-error line numbers.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
Likewise.
* testsuite/20_util/declval/requirements/1_neg.cc: Likewise.

From-SVN: r173222

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/type_traits
libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc

index 5dfeb777dcb0a26c2704e98c44a21a5acb5a6ffc..8e509aa7500d920e6a66545ef742ca2bca0077e4 100644 (file)
@@ -1,3 +1,20 @@
+2011-04-30  Daniel Krugler  <daniel.kruegler@googlemail.com>
+
+       * include/std/type_traits (__is_default_constructible_atom,
+       __is_default_constructible_safe<, true>,
+       __is_direct_constructible_new_safe,
+       __is_base_to_derived_ref<,, true>, __is_lvalue_to_rvalue_ref<,, true>,
+       __is_direct_constructible_ref_cast, __is_direct_constructible,
+       __is_nary_constructible): Simplify; add comments throughout.
+
+2011-04-30  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * testsuite/20_util/make_signed/requirements/typedefs_neg.cc:
+       Adjust dg-error line numbers.
+       * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
+       Likewise.
+       * testsuite/20_util/declval/requirements/1_neg.cc: Likewise.
+
 2011-04-30  Doug Kwan  <dougkwan@google.com>
 
        * include/Makefile.am (install-freestanding-headers): Also install
index 6d33416c330fdb065dce12a799748d786dd92553..0560522cbfd1cc11e2babeb279389b8e1570542d 100644 (file)
@@ -550,7 +550,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __is_array_unknown_bounds
     : public __and_<is_array<_Tp>, __not_<extent<_Tp>>>::type
     { };
-
+    
+  // In N3290 is_destructible does not say anything about function 
+  // types and abstract types, see LWG 2049. This implementation
+  // describes function types as trivially nothrow destructible and
+  // abstract types as destructible, iff the  explicit destructor
+  // call expression is wellformed.
   struct __do_is_destructible_impl_1
   {
     template<typename _Up>
@@ -571,6 +576,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef decltype(__test<_Tp>(0)) type;
     };
 
+  // Special implementation for abstract types
   struct __do_is_destructible_impl_2
   {
     template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
@@ -632,23 +638,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp>
     struct __is_default_constructible_atom
-    : public __and_<is_destructible<_Tp>,
-                    __is_default_constructible_impl<_Tp>>::type::type
+    : public __and_<__not_<is_void<_Tp>>,
+                    __is_default_constructible_impl<_Tp>>::type
     { };
 
   template<typename _Tp, bool = is_array<_Tp>::value>
     struct __is_default_constructible_safe;
 
-  // The following technique is a workaround for a gcc defect, which does
-  // not sfinae away attempts to default-construct arrays of unknown bounds.
-  // Complete arrays can be default-constructed, if the element type is
-  // default-constructible, but arrays with unknown bounds are not:
-
+  // The following technique is a workaround for a current core language
+  // restriction, which does not allow for array types to occur in 
+  // functional casts of the form T().  Complete arrays can be default-
+  // constructed, if the element type is default-constructible, but 
+  // arrays with unknown bounds are not.
   template<typename _Tp>
     struct __is_default_constructible_safe<_Tp, true>
     : public __and_<__is_array_known_bounds<_Tp>,
                    __is_default_constructible_atom<typename
-                      remove_all_extents<_Tp>::type>>::type::type
+                      remove_all_extents<_Tp>::type>>::type
     { };
 
   template<typename _Tp>
@@ -663,6 +669,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                      _Tp>::value)>
     { };
 
+
+  // Implementation of is_constructible.
+
+  // The hardest part of this trait is the binary direct-initialization
+  // case, because we hit into a functional cast of the form T(arg).
+  // This implementation uses different strategies depending on the
+  // target type to reduce the test overhead as much as possible:
+  //
+  // a) For a reference target type, we use a static_cast expression 
+  //    modulo its extra cases.
+  //
+  // b) For a non-reference target type we use a ::new expression.
   struct __do_is_static_castable_impl
   {
     template<typename _From, typename _To, typename
@@ -682,8 +700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _From, typename _To>
     struct __is_static_castable_safe
-    : public __and_<__or_<is_void<_To>, is_destructible<_To>>,
-                    __is_static_castable_impl<_From, _To>>::type::type
+    : public __is_static_castable_impl<_From, _To>::type
     { };
 
   // __is_static_castable
@@ -693,6 +710,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                      _From, _To>::value)>
     { };
 
+  // Implementation for non-reference types. To meet the proper
+  // variable definition semantics, we also need to test for
+  // is_destructible in this case.
   struct __do_is_direct_constructible_impl
   {
     template<typename _Tp, typename _Arg, typename
@@ -713,7 +733,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp, typename _Arg>
     struct __is_direct_constructible_new_safe
     : public __and_<is_destructible<_Tp>,
-                    __is_direct_constructible_impl<_Tp, _Arg>>::type::type
+                    __is_direct_constructible_impl<_Tp, _Arg>>::type
     { };
 
   template<typename, typename>
@@ -736,10 +756,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         >::type>::type __src_t;
       typedef typename remove_cv<typename remove_reference<_To
         >::type>::type __dst_t;
-      typedef typename __and_<
-        __not_<is_same<__src_t, __dst_t>>,
-        is_base_of<__src_t, __dst_t>
-      >::type type;
+      typedef __and_<__not_<is_same<__src_t, __dst_t>>,
+                    is_base_of<__src_t, __dst_t>> type;
       static constexpr bool value = type::value;
     };
 
@@ -760,10 +778,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         _From>::type>::type __src_t;
       typedef typename remove_cv<typename remove_reference<
         _To>::type>::type __dst_t;
-      typedef typename __or_<
-        is_same<__src_t, __dst_t>,
-        is_base_of<__dst_t, __src_t>
-      >::type type;
+      typedef __or_<is_same<__src_t, __dst_t>,
+                   is_base_of<__dst_t, __src_t>> type;
       static constexpr bool value = type::value;
     };
 
@@ -772,25 +788,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : public false_type
     { };
 
-  // Here we handle direct-initialization to a reference type
-  // as equivalent to a static_cast modulo overshooting conversions.
-  // These are restricted to the following conversion:
-  //    a) A base class to a derived class reference
-  //    b) An lvalue-reference to an rvalue-reference
-
+  // Here we handle direct-initialization to a reference type as 
+  // equivalent to a static_cast modulo overshooting conversions.
+  // These are restricted to the following conversions:
+  //    a) A glvalue of a base class to a derived class reference
+  //    b) An lvalue to an rvalue-reference of reference-compatible 
+  //       types
   template<typename _Tp, typename _Arg>
     struct __is_direct_constructible_ref_cast
     : public __and_<__is_static_castable<_Arg, _Tp>,
                     __not_<__or_<__is_base_to_derived_ref<_Arg, _Tp>,
                                  __is_lvalue_to_rvalue_ref<_Arg, _Tp>
-                   >>>::type::type
+                   >>>::type
     { };
 
-  // Direct-initialization is tricky, because of functional
-  // casts: For a conversion to reference we fall back to a
-  // static_cast modulo extra cases, otherwise we use a
-  // new expression:
-
   template<typename _Tp, typename _Arg>
     struct __is_direct_constructible_new
     : public conditional<is_reference<_Tp>::value,
@@ -802,9 +813,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp, typename _Arg>
     struct __is_direct_constructible
     : public integral_constant<bool, (__is_direct_constructible_new<
-                                     _Tp, _Arg>::type::value)>
+                                     _Tp, _Arg>::value)>
     { };
 
+  // Since default-construction and binary direct-initialization have
+  // been handled separately, the implementation of the remaining
+  // n-ary construction cases is rather straightforward.
   struct __do_is_nary_constructible_impl
   {
     template<typename _Tp, typename... _Args, typename
@@ -824,9 +838,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _Tp, typename... _Args>
     struct __is_nary_constructible
-    : public __and_<is_destructible<_Tp>,
-                   __is_nary_constructible_impl<_Tp, _Args...>
-                   >::type::type
+    : public __is_nary_constructible_impl<_Tp, _Args...>::type
     {
       static_assert(sizeof...(_Args) > 1,
                     "Only useful for > 1 arguments");
index af1522b7a40ac13a082cf3a10e93e8227c997a59..4fa005ecdd6689afa60c00ff42f809b259bf689a 100644 (file)
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 1603 }
+// { dg-error "static assertion failed" "" { target *-*-* } 1615 }
 
 #include <utility>
 
index 871bbe571e7df8c92db6e7f30f366068ee028ee0..01a2068e6e7ee01e629a432ef755b18f36174869 100644 (file)
@@ -48,5 +48,5 @@ void test01()
 // { dg-error "instantiated from here" "" { target *-*-* } 40 }
 // { dg-error "instantiated from here" "" { target *-*-* } 42 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1389 }
-// { dg-error "declaration of" "" { target *-*-* } 1353 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1401 }
+// { dg-error "declaration of" "" { target *-*-* } 1365 }
index edcce7cf0f52a475a91b17b4764701e5c33a9268..7dd19d63127a4db0e7106b96cf8575bc013c94bd 100644 (file)
@@ -48,5 +48,5 @@ void test01()
 // { dg-error "instantiated from here" "" { target *-*-* } 40 }
 // { dg-error "instantiated from here" "" { target *-*-* } 42 }
 
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1313 }
-// { dg-error "declaration of" "" { target *-*-* } 1277 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1325 }
+// { dg-error "declaration of" "" { target *-*-* } 1289 }