From patchwork Mon Jun 20 11:09:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 101092 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 4FCA9B6FDB for ; Mon, 20 Jun 2011 21:09:08 +1000 (EST) Received: (qmail 24207 invoked by alias); 20 Jun 2011 11:09:06 -0000 Received: (qmail 24186 invoked by uid 22791); 20 Jun 2011 11:09:03 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL, BAYES_05, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from smtp207.alice.it (HELO smtp207.alice.it) (82.57.200.103) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 20 Jun 2011 11:08:47 +0000 Received: from [192.168.1.4] (79.52.193.1) by smtp207.alice.it (8.5.124.08) id 4DFA189A004E8E94; Mon, 20 Jun 2011 13:08:45 +0200 Message-ID: <4DFF2A6B.4030603@oracle.com> Date: Mon, 20 Jun 2011 13:09:31 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110414 SUSE/3.1.10 Thunderbird/3.1.10 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: libstdc++ , Dodji Seketeli Subject: [v3] Remove tuple<_Tp> spec (and add wa for c++/48322 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, tested x86_64-linux, committed to mainline. Thanks, Paolo. PS: Dodji, this is the tricky C++ issue we were talking about. 2011-06-20 Daniel Krugler Paolo Carlini * include/std/tuple (__conv_types, __one_by_one_convertible, __all_convertible): Add. (tuple): Use the latter. (tuple<_T1>): Remove. * testsuite/20_util/uses_allocator/cons_neg.cc: Adjust dg-error line number. * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Likewise. Index: include/std/tuple =================================================================== --- include/std/tuple (revision 175203) +++ include/std/tuple (working copy) @@ -69,6 +69,35 @@ struct __add_r_ref<_Tp&> { typedef _Tp& type; }; + // To work around c++/49225 aka c++/48322. + template + struct __conv_types { }; + + template + struct __one_by_one_convertible + : public false_type { }; + + template + struct __one_by_one_convertible<__conv_types<_Tp>, __conv_types<_Up>> + : public is_convertible<_Tp, _Up>::type { }; + + template + struct __one_by_one_convertible<__conv_types<_T1, _TR...>, + __conv_types<_U1, _UR...>> + : public __and_, + __one_by_one_convertible<__conv_types<_TR...>, + __conv_types<_UR...>>>::type + { }; + + template + struct __all_convertible; + + template + struct __all_convertible<__conv_types<_TTypes...>, + __conv_types<_UTypes...>> + : public __one_by_one_convertible<__conv_types<_TTypes...>, + __conv_types<_UTypes...>>::type { }; + template struct _Head_base; @@ -359,8 +388,9 @@ template, - __and_...>>::value>::type> + __all_convertible<__conv_types<_UElements...>, + __conv_types<_Elements...>> + >::value>::type> explicit tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } @@ -371,8 +401,9 @@ template, - __and_...>>::value>::type> + __all_convertible<__conv_types, + __conv_types<_Elements...>> + >::value>::type> tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast&>(__in)) { } @@ -380,8 +411,9 @@ template, - __and_...>>::value>::type> + __all_convertible<__conv_types<_UElements...>, + __conv_types<_Elements...>> + >::value>::type> tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } @@ -628,112 +660,7 @@ { _Inherited::_M_swap(__in); } }; - /// tuple (1-element). - // TODO: Should be simply removed when c++/49225 is fixed, worst case - // together with a different way to constrain the constructors - // of the primary template. - template - class tuple<_T1> : public _Tuple_impl<0, _T1> - { - typedef _Tuple_impl<0, _T1> _Inherited; - public: - constexpr tuple() - : _Inherited() { } - - explicit - constexpr tuple(const _T1& __a1) - : _Inherited(__a1) { } - - template::value>::type> - explicit - tuple(_U1&& __a1) - : _Inherited(std::forward<_U1>(__a1)) { } - - constexpr tuple(const tuple&) = default; - tuple(tuple&&) = default; - - template::value>::type> - tuple(const tuple<_U1>& __in) - : _Inherited(static_cast&>(__in)) { } - - template::value>::type> - tuple(tuple<_U1>&& __in) - : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } - - // allocator-extended constructors - - template - tuple(allocator_arg_t __tag, const _Alloc& __a) - : _Inherited(__tag, __a) { } - - template - tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1) - : _Inherited(__tag, __a, __a1) { } - - // TODO: constrain for is_uses_allocator_constructible<_T1, _U1&&, _Alloc> - template - tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1) - : _Inherited(__tag, __a, std::forward<_U1>(__a1)) { } - - template - tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) - : _Inherited(__tag, __a, static_cast(__in)) { } - - template - tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) - : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } - - template - tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1>& __in) - : _Inherited(__tag, __a, static_cast&>(__in)) - { } - - template - tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1>&& __in) - : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } - - tuple& - operator=(const tuple& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - tuple& - operator=(tuple&& __in) - noexcept(is_nothrow_move_assignable<_Inherited>::value) - { - static_cast<_Inherited&>(*this) = std::move(__in); - return *this; - } - - template - tuple& - operator=(const tuple<_U1>& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - template - tuple& - operator=(tuple<_U1>&& __in) - { - static_cast<_Inherited&>(*this) = std::move(__in); - return *this; - } - - void - swap(tuple& __in) - noexcept(noexcept(__in._M_swap(__in))) - { _Inherited::_M_swap(__in); } - }; - - /// Gives the type of the ith element of a given tuple type. template struct tuple_element; Index: testsuite/20_util/uses_allocator/cons_neg.cc =================================================================== --- testsuite/20_util/uses_allocator/cons_neg.cc (revision 175202) +++ testsuite/20_util/uses_allocator/cons_neg.cc (working copy) @@ -44,4 +44,4 @@ tuple t(allocator_arg, a, 1); } -// { dg-error "no matching function" "" { target *-*-* } 112 } +// { dg-error "no matching function" "" { target *-*-* } 141 } Index: testsuite/20_util/weak_ptr/comparison/cmp_neg.cc =================================================================== --- testsuite/20_util/weak_ptr/comparison/cmp_neg.cc (revision 175202) +++ testsuite/20_util/weak_ptr/comparison/cmp_neg.cc (working copy) @@ -51,7 +51,7 @@ // { dg-warning "note" "" { target *-*-* } 485 } // { dg-warning "note" "" { target *-*-* } 479 } // { dg-warning "note" "" { target *-*-* } 469 } -// { dg-warning "note" "" { target *-*-* } 887 } +// { dg-warning "note" "" { target *-*-* } 814 } // { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 1050 } // { dg-warning "note" "" { target *-*-* } 342 }