From patchwork Fri Apr 5 20:12:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Patchwork-Id: 234269 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id DB37B2C00EF for ; Sat, 6 Apr 2013 07:13:13 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=BHIJCGLO07pDzSEHi KxrluI3vVuJ2RX8JwLXRFCAJJk27NEHyqvSRHSMXIjIpjEjOMMAfsWTsgWWa8Sp3 vyV4QQXx6OuTPcQ0i5mKj/cSEjUTx6PVYNXiZi81FLfMOuz9FetitAJYUoZVt2Mb EaHli1j1Cb7gRLWEihvXKdooYs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=mdmcUgi5xTx3RWnPw21pawU JZBQ=; b=F2lyZbxKFktJrBEj7IhQ9917Dqw+r+kXY1ROAlaiqkqclZakR1Mei+j Q3k8CW4q5VTz1OP2TF31FhOEfjBsyG72GUZnVZjaz9I08n+wQCUJUmd6oRLHuQaF OgGks8yrrJyxycM4ja7sykOMIH+KCiwy7obnQ5Q3d72FEIH9nHjU= Received: (qmail 6189 invoked by alias); 5 Apr 2013 20:13:07 -0000 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 Received: (qmail 6172 invoked by uid 89); 5 Apr 2013 20:13:06 -0000 X-Spam-SWARE-Status: No, score=-5.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE autolearn=ham version=3.3.1 X-Spam-User: qpsmtpd, 2 recipients Received: from mail-wg0-f46.google.com (HELO mail-wg0-f46.google.com) (74.125.82.46) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 05 Apr 2013 20:13:01 +0000 Received: by mail-wg0-f46.google.com with SMTP id l18so4059726wgh.1 for ; Fri, 05 Apr 2013 13:12:59 -0700 (PDT) X-Received: by 10.194.178.9 with SMTP id cu9mr19065059wjc.39.1365192779494; Fri, 05 Apr 2013 13:12:59 -0700 (PDT) Received: from localhost.localdomain (arf62-1-82-237-250-248.fbx.proxad.net. [82.237.250.248]) by mx.google.com with ESMTPS id o5sm6456435wix.3.2013.04.05.13.12.57 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 05 Apr 2013 13:12:58 -0700 (PDT) Message-ID: <515F3049.5060403@gmail.com> Date: Fri, 05 Apr 2013 22:12:57 +0200 From: =?ISO-8859-1?Q?Fran=E7ois_Dumont?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120829 Thunderbird/15.0 MIME-Version: 1.0 To: Jonathan Wakely CC: "libstdc++@gcc.gnu.org" , gcc-patches Subject: Re: functional and type_traits cleanup References: <515DDF9F.1050809@gmail.com> In-Reply-To: X-Virus-Found: No On 04/05/2013 12:20 AM, Jonathan Wakely wrote: > On 4 April 2013 21:16, François Dumont wrote: > I think this is mostly very good, thanks for cleaning it up. The > indentiation of the closing brace for __is_assignable_helper looks > wrong. Is there a reason that __is_assignable_helper::__test uses a > default template argument but __is_convertible_helper::__test uses > decltype(expr, type) in the function return type? I think the > decltype(__test_aux<_Tp1>(...)) expression would work as a default > template argument too, which I find easier to read because it doesn't > clutter up the return type. In fact my first attempt was a very simple one: template class __is_convertible_helper<_From, _To, false> { template static true_type __test(_To1); template static false_type __test(...); public: typedef decltype(__test<_To>(std::declval<_From>())) type; }; But some tests failed like: In file included from /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/move.h:57:0, from /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/stl_pair.h:59, from /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/utility:70, from /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/tuple:38, from /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/functional:55, from /home/fdt/dev/gcc/src/libstdc++-v3/testsuite/20_util/bind/38889.cc:23: /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits: In instantiation of 'struct std::__is_convertible_helper >&, std::_Placeholder<1>, false>': /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:1321:12: required from 'struct std::is_convertible >&, std::_Placeholder<1> >' /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:111:12: required from 'struct std::__and_ >&, std::_Placeholder<1> > >' /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/tuple:400:40: required from 'struct std::_Bind))(int)>' /home/fdt/dev/gcc/src/libstdc++-v3/testsuite/20_util/bind/38889.cc:28:41: required from here /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:1316:30: error: 'std::_Placeholder<1>' is an inaccessible base of 'std::tuple >' typedef decltype(__test<_To>(std::declval<_From>())) type; ^ /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:1309:2: error: initializing argument 1 of 'static std::true_type std::__is_convertible_helper<_From, _To, false>::__test(_To1) [with _To1 = std::_Placeholder<1>; _From = const std::tuple >&; _To = std::_Placeholder<1>; std::true_type = std::integral_constant]' __test(_To1); ^ From my point of view this is an other example of use case for which gcc is not SFINAE friendly enough, no ? But the version with the default template parameter is fine and more consistent with the other helpers implementation so, adopted! Here is an other version of the patch for validation. Daniel, I agree that inheritance with integral_constant is not as obvious as before but it is still there and it is just what the compiler need. I even hope that it also simplified a (very) little bit the job for the compiler. Ok to commit ? François Index: include/std/functional =================================================================== --- include/std/functional (revision 197307) +++ include/std/functional (working copy) @@ -185,38 +185,6 @@ : _Weak_result_type_impl::type> { }; - /// Determines if the type _Tp derives from unary_function. - template - struct _Derives_from_unary_function : __sfinae_types - { - private: - template - static __one __test(const volatile unary_function<_T1, _Res>*); - - // It's tempting to change "..." to const volatile void*, but - // that fails when _Tp is a function type. - static __two __test(...); - - public: - static const bool value = sizeof(__test((_Tp*)0)) == 1; - }; - - /// Determines if the type _Tp derives from binary_function. - template - struct _Derives_from_binary_function : __sfinae_types - { - private: - template - static __one __test(const volatile binary_function<_T1, _T2, _Res>*); - - // It's tempting to change "..." to const volatile void*, but - // that fails when _Tp is a function type. - static __two __test(...); - - public: - static const bool value = sizeof(__test((_Tp*)0)) == 1; - }; - /** * Invoke a function object, which may be either a member pointer or a * function object. The first parameter will tell which. Index: include/std/type_traits =================================================================== --- include/std/type_traits (revision 197307) +++ include/std/type_traits (working copy) @@ -127,12 +127,6 @@ : public integral_constant { }; - struct __sfinae_types - { - typedef char __one; - typedef struct { char __arr[2]; } __two; - }; - // For several sfinae-friendly trait implementations we transport both the // result information (as the member type) and the failure information (no // member type). This is very similar to std::enable_if, but we cannot use @@ -161,8 +155,7 @@ /// is_void template struct is_void - : public integral_constant::type>::value)> + : public __is_void_helper::type>::type { }; template @@ -244,8 +237,7 @@ /// is_integral template struct is_integral - : public integral_constant::type>::value)> + : public __is_integral_helper::type>::type { }; template @@ -273,8 +265,7 @@ /// is_floating_point template struct is_floating_point - : public integral_constant::type>::value)> + : public __is_floating_point_helper::type>::type { }; /// is_array @@ -301,8 +292,7 @@ /// is_pointer template struct is_pointer - : public integral_constant::type>::value)> + : public __is_pointer_helper::type>::type { }; /// is_lvalue_reference @@ -337,8 +327,8 @@ /// is_member_object_pointer template struct is_member_object_pointer - : public integral_constant::type>::value)> + : public __is_member_object_pointer_helper< + typename remove_cv<_Tp>::type>::type { }; template @@ -352,8 +342,8 @@ /// is_member_function_pointer template struct is_member_function_pointer - : public integral_constant::type>::value)> + : public __is_member_function_pointer_helper< + typename remove_cv<_Tp>::type>::type { }; /// is_enum @@ -422,8 +412,7 @@ // __is_nullptr_t (extension). template struct __is_nullptr_t - : public integral_constant::type>::value)> + : public __is_nullptr_t_helper::type>::type { }; // Composite type categories. @@ -480,8 +469,7 @@ /// is_member_pointer template struct is_member_pointer - : public integral_constant::type>::value)> + : public __is_member_pointer_helper::type>::type { }; // Type properties. @@ -567,7 +555,7 @@ /// is_signed template struct is_signed - : public integral_constant::value> + : public __is_signed_helper<_Tp>::type { }; /// is_unsigned @@ -650,7 +638,7 @@ /// is_destructible template struct is_destructible - : public integral_constant::value)> + : public __is_destructible_safe<_Tp>::type { }; // is_nothrow_destructible requires that is_destructible is @@ -698,7 +686,7 @@ /// is_nothrow_destructible template struct is_nothrow_destructible - : public integral_constant::value)> + : public __is_nt_destructible_safe<_Tp>::type { }; struct __do_is_default_constructible_impl @@ -746,8 +734,7 @@ /// is_default_constructible template struct is_default_constructible - : public integral_constant::value)> + : public __is_default_constructible_safe<_Tp>::type { }; @@ -901,8 +888,7 @@ template struct __is_direct_constructible - : public integral_constant::value)> + : public __is_direct_constructible_new<_Tp, _Arg>::type { }; // Since default-construction and binary direct-initialization have @@ -953,8 +939,7 @@ /// is_constructible template struct is_constructible - : public integral_constant::value)> + : public __is_constructible_impl<_Tp, _Args...>::type { }; template::value> @@ -1081,24 +1066,24 @@ template class __is_assignable_helper - : public __sfinae_types { - template - static decltype(declval<_Tp1>() = declval<_Up1>(), __one()) + template() = declval<_Up1>())> + static true_type __test(int); template - static __two __test(...); + static false_type + __test(...); public: - static constexpr bool value = sizeof(__test<_Tp, _Up>(0)) == 1; + typedef decltype(__test<_Tp, _Up>(0)) type; }; /// is_assignable template struct is_assignable - : public integral_constant::value> + : public __is_assignable_helper<_Tp, _Up>::type { }; template::value> @@ -1292,31 +1277,32 @@ bool = __or_, is_function<_To>, is_array<_To>>::value> struct __is_convertible_helper - { static constexpr bool value = is_void<_To>::value; }; + { typedef typename is_void<_To>::type type; }; template class __is_convertible_helper<_From, _To, false> - : public __sfinae_types { - template - static void __test_aux(_To1); + template + static void __test_aux(_To1); - template - static decltype(__test_aux<_To1>(std::declval<_From1>()), __one()) + template(std::declval<_From1>()))> + static true_type __test(int); template - static __two __test(...); + static false_type + __test(...); public: - static constexpr bool value = sizeof(__test<_From, _To>(0)) == 1; + typedef decltype(__test<_From, _To>(0)) type; }; + /// is_convertible template struct is_convertible - : public integral_constant::value> + : public __is_convertible_helper<_From, _To>::type { }; @@ -2041,29 +2027,28 @@ * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. */ -#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ - template \ - class __has_##_NTYPE##_helper \ - : __sfinae_types \ - { \ - template \ - struct _Wrap_type \ - { }; \ - \ - template \ - static __one __test(_Wrap_type*); \ - \ - template \ - static __two __test(...); \ - \ - public: \ - static constexpr bool value = sizeof(__test<_Tp>(0)) == 1; \ - }; \ - \ - template \ - struct __has_##_NTYPE \ - : integral_constant::type>::value> \ +#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ + template \ + class __has_##_NTYPE##_helper \ + { \ + template \ + struct _Wrap_type \ + { }; \ + \ + template \ + static true_type __test(_Wrap_type*); \ + \ + template \ + static false_type __test(...); \ + \ + public: \ + typedef decltype(__test<_Tp>(0)) type; \ + }; \ + \ + template \ + struct __has_##_NTYPE \ + : public __has_##_NTYPE##_helper \ + ::type>::type \ { }; _GLIBCXX_END_NAMESPACE_VERSION Index: testsuite/20_util/reference_wrapper/typedefs-3.cc =================================================================== --- testsuite/20_util/reference_wrapper/typedefs-3.cc (revision 197307) +++ testsuite/20_util/reference_wrapper/typedefs-3.cc (working copy) @@ -44,7 +44,8 @@ struct S012 : S0, S1, S2 { }; -using std::__sfinae_types; +using std::true_type; +using std::false_type; using std::integral_constant; using std::remove_cv; Index: testsuite/20_util/make_signed/requirements/typedefs_neg.cc =================================================================== --- testsuite/20_util/make_signed/requirements/typedefs_neg.cc (revision 197307) +++ testsuite/20_util/make_signed/requirements/typedefs_neg.cc (working copy) @@ -48,5 +48,5 @@ // { dg-error "required from here" "" { target *-*-* } 40 } // { dg-error "required from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1613 } -// { dg-error "declaration of" "" { target *-*-* } 1577 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1597 } +// { dg-error "declaration of" "" { target *-*-* } 1561 } Index: testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc =================================================================== --- testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc (revision 197307) +++ testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc (working copy) @@ -48,5 +48,5 @@ // { dg-error "required from here" "" { target *-*-* } 40 } // { dg-error "required from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1531 } -// { dg-error "declaration of" "" { target *-*-* } 1495 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1515 } +// { dg-error "declaration of" "" { target *-*-* } 1479 } Index: testsuite/20_util/declval/requirements/1_neg.cc =================================================================== --- testsuite/20_util/declval/requirements/1_neg.cc (revision 197307) +++ 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 *-*-* } 1871 } +// { dg-error "static assertion failed" "" { target *-*-* } 1855 } #include Index: testsuite/20_util/bind/ref_neg.cc =================================================================== --- testsuite/20_util/bind/ref_neg.cc (revision 197307) +++ testsuite/20_util/bind/ref_neg.cc (working copy) @@ -30,10 +30,10 @@ { const int dummy = 0; std::bind(&inc, _1)(0); // { dg-error "no match" } - // { dg-error "rvalue|const" "" { target *-*-* } 1347 } - // { dg-error "rvalue|const" "" { target *-*-* } 1361 } - // { dg-error "rvalue|const" "" { target *-*-* } 1375 } - // { dg-error "rvalue|const" "" { target *-*-* } 1389 } + // { dg-error "rvalue|const" "" { target *-*-* } 1315 } + // { dg-error "rvalue|const" "" { target *-*-* } 1329 } + // { dg-error "rvalue|const" "" { target *-*-* } 1343 } + // { dg-error "rvalue|const" "" { target *-*-* } 1357 } std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" } }