From patchwork Sat Apr 30 19:42:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 93508 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 65CAFB6F57 for ; Sun, 1 May 2011 05:43:03 +1000 (EST) Received: (qmail 4581 invoked by alias); 30 Apr 2011 19:42:59 -0000 Received: (qmail 4564 invoked by uid 22791); 30 Apr 2011 19:42:57 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from smtp208.alice.it (HELO smtp208.alice.it) (82.57.200.104) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 30 Apr 2011 19:42:38 +0000 Received: from [192.168.1.4] (79.51.25.42) by smtp208.alice.it (8.5.124.08) id 4C1A271618689DA4; Sat, 30 Apr 2011 21:42:34 +0200 Message-ID: <4DBC6608.2050502@oracle.com> Date: Sat, 30 Apr 2011 21:42:00 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.14) Gecko/20110221 SUSE/3.1.8 Thunderbird/3.1.8 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: libstdc++ , =?ISO-8859-1?Q?Daniel_Kr=FCgler?= Subject: [v3] Small tweaks to X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, I received from Daniel the below small tweaks and additional comments to , which I have very slightly tweaked, regtested on x86_64-linux, and applied to mainline. Thanks, Paolo. /////////////////// 2011-04-30 Daniel Krugler * 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 * 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. Index: include/std/type_traits =================================================================== --- include/std/type_traits (revision 173221) +++ include/std/type_traits (working copy) @@ -550,7 +550,12 @@ struct __is_array_unknown_bounds : public __and_, __not_>>::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 @@ -571,6 +576,7 @@ typedef decltype(__test<_Tp>(0)) type; }; + // Special implementation for abstract types struct __do_is_destructible_impl_2 { template().~_Tp())> @@ -632,23 +638,23 @@ template struct __is_default_constructible_atom - : public __and_, - __is_default_constructible_impl<_Tp>>::type::type + : public __and_<__not_>, + __is_default_constructible_impl<_Tp>>::type { }; template::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 struct __is_default_constructible_safe<_Tp, true> : public __and_<__is_array_known_bounds<_Tp>, __is_default_constructible_atom::type>>::type::type + remove_all_extents<_Tp>::type>>::type { }; template @@ -663,6 +669,18 @@ _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 struct __is_static_castable_safe - : public __and_<__or_, 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 @@ _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 struct __is_direct_constructible_new_safe : public __and_, - __is_direct_constructible_impl<_Tp, _Arg>>::type::type + __is_direct_constructible_impl<_Tp, _Arg>>::type { }; template @@ -736,10 +756,8 @@ >::type>::type __src_t; typedef typename remove_cv::type>::type __dst_t; - typedef typename __and_< - __not_>, - is_base_of<__src_t, __dst_t> - >::type type; + typedef __and_<__not_>, + is_base_of<__src_t, __dst_t>> type; static constexpr bool value = type::value; }; @@ -760,10 +778,8 @@ _From>::type>::type __src_t; typedef typename remove_cv::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_base_of<__dst_t, __src_t>> type; static constexpr bool value = type::value; }; @@ -772,25 +788,20 @@ : 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 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 struct __is_direct_constructible_new : public conditional::value, @@ -802,9 +813,12 @@ template struct __is_direct_constructible : public integral_constant::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 struct __is_nary_constructible - : public __and_, - __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: testsuite/20_util/make_signed/requirements/typedefs_neg.cc =================================================================== --- testsuite/20_util/make_signed/requirements/typedefs_neg.cc (revision 173221) +++ testsuite/20_util/make_signed/requirements/typedefs_neg.cc (working copy) @@ -48,5 +48,5 @@ // { 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: testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc =================================================================== --- testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc (revision 173221) +++ testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc (working copy) @@ -48,5 +48,5 @@ // { 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 } Index: testsuite/20_util/declval/requirements/1_neg.cc =================================================================== --- testsuite/20_util/declval/requirements/1_neg.cc (revision 173221) +++ testsuite/20_util/declval/requirements/1_neg.cc (working copy) @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // . -// { dg-error "static assertion failed" "" { target *-*-* } 1603 } +// { dg-error "static assertion failed" "" { target *-*-* } 1615 } #include