From patchwork Tue Sep 16 15:17:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 120362 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C98583857733 for ; Tue, 16 Sep 2025 15:21:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C98583857733 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Z9D4o5jV X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 0041A3858D39 for ; Tue, 16 Sep 2025 15:18:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0041A3858D39 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0041A3858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758035929; cv=none; b=fhabs0Zqjsnh1OxZRy3vdRtO/l3nQ7RZDEuwTwmcIiYUZHy2Rci09iNHWrKbW80zoCD1eeYqe0+8ckucyGR/bouPyB1H58EVGljXaT8LC3RJx+o5lPXzzi8nIq9oFGTtVqKlZtnF46ggHaqQeOBLCdBnQ+51YuVuY3P/FBaG7fc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758035929; c=relaxed/simple; bh=SbCs6PNAAaRdGcMwRURIQ7XPZyYTXhdL8MgMvofS2Pk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=P0JKRULnqQdAPJB2JDdjITD6fi8iOF5QU1oukuuJSzOqOHdMfvAblS+S2PmG/Kpv54mE8JpdxXxLRZDsSWKYtRhLfh1WIE/CUyTl+bh4uX28Uj9WH5OlHANfIcmEeMskR1ZoQ56Kwz0EnZ9tAoeKME/CHovbBgoZ7qPfpQJmEmU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0041A3858D39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758035928; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=irTF8y27n6TuPGe40n7eL7t9wLKdveF13ulP41T8+oI=; b=Z9D4o5jVe6Y4uuG8QR9B71F/1o/PvDFTfsuOOQiUQIwkPoa9ifh04utTom3YuU6i+yf2IQ doN4Y7uanB5d8JXdSEU4oS0AFZTQdSEsHwMmJaV5qmmWaiBV8esasnrJdFNRn8wzGIaxRU ryPWxFDwLauMUsLvZXgzXAHUnOyxyjM= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-641-jwSQRrrEPqibHsf4cfRHCg-1; Tue, 16 Sep 2025 11:18:47 -0400 X-MC-Unique: jwSQRrrEPqibHsf4cfRHCg-1 X-Mimecast-MFC-AGG-ID: jwSQRrrEPqibHsf4cfRHCg_1758035926 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 393DC180057D; Tue, 16 Sep 2025 15:18:46 +0000 (UTC) Received: from zen.kayari.org (unknown [10.42.28.4]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D735A19560B8; Tue, 16 Sep 2025 15:18:44 +0000 (UTC) From: Jonathan Wakely To: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org Subject: [PATCH] libstdc++: Optimize determination of std::tuple_cat return type Date: Tue, 16 Sep 2025 16:17:10 +0100 Message-ID: <20250916151843.2680202-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: nH9VntcOuUNgUvEa-oXPChX34oXQZ_Dlzmz93VdpiTs_1758035926 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_HOSTKARMA_W, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org The std::tuple_cat function has to determine a std::tuple return type from zero or more tuple-like arguments. This uses the __make_tuple class template to transform a tuple-like type into a std::tuple, and the __combine_tuples class template to combine zero or more std::tuple types into a single std::tuple type. This change optimizes the __make_tuple class template to use an _Index_tuple and pack expansion instead of recursive instantiation, and optimizes __combine_tuples to use fewer levels of recursion. For ranges::adjacent_view's __detail::__repeated_tuple helper we can just use the __make_tuple class template directly, instead of doing overload resolution on std::tuple_cat to get its return type. libstdc++-v3/ChangeLog: * include/std/ranges (__detail::__repeated_tuple): Use __make_tuple helper alias directly, instead of doing overload resolution on std::tuple_cat. * include/std/tuple (__make_tuple_impl): Remove. (__do_make_tuple): Replace recursion with _Index_tuple and pack expansion. (__make_tuple): Adjust to new __do_make_tuple definition. (__combine_tuples, tuple, Rem...>): Replace with a partial specialization for exactly two tuples and a partial specialization for three or more tuples. --- Tested powerpc64le-linux. libstdc++-v3/include/std/ranges | 2 +- libstdc++-v3/include/std/tuple | 51 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index f493da56203b..6c64f4c36213 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -5383,7 +5383,7 @@ namespace views::__adaptor { // Yields tuple<_Tp, ..., _Tp> with _Nm elements. template - using __repeated_tuple = decltype(std::tuple_cat(std::declval>())); + using __repeated_tuple = typename __make_tuple>::__type; // For a functor F that is callable with N arguments, the expression // declval<__unarize>(x) is equivalent to declval(x, ..., x). diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 2e6499eab22d..0ca616f1b4fb 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -2681,54 +2681,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } /// @cond undocumented - template - struct __make_tuple_impl; + template + struct __do_make_tuple; - template - struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> - : __make_tuple_impl<_Idx + 1, - tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, - _Tuple, _Nm> - { }; - - template - struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> + template + struct __do_make_tuple<_Tuple, _Index_tuple<_Idx...>> { - typedef tuple<_Tp...> __type; + using __type = tuple<__tuple_element_t<_Idx, _Tuple>...>; }; - template - struct __do_make_tuple - : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value> - { }; - // Returns the std::tuple equivalent of a tuple-like type. - template + template, + typename _Indices = _Build_index_tuple::value>> struct __make_tuple - : public __do_make_tuple<__remove_cvref_t<_Tuple>> + : __do_make_tuple<_Tup, typename _Indices::__type> { }; - // Combines several std::tuple's into a single one. + // Combines several std::tuple types into a single one. template struct __combine_tuples; template<> struct __combine_tuples<> { - typedef tuple<> __type; + using __type = tuple<>; }; template struct __combine_tuples> { - typedef tuple<_Ts...> __type; + using __type = tuple<_Ts...>; }; - template - struct __combine_tuples, tuple<_T2s...>, _Rem...> + template + struct __combine_tuples, tuple<_T2s...>> { - typedef typename __combine_tuples, - _Rem...>::__type __type; + using __type = tuple<_T1s..., _T2s...>; + }; + + template + struct __combine_tuples, tuple<_T2s...>, tuple<_T3s...>, + _Rem...> + { + using _First = tuple<_T1s..., _T2s..., _T3s...>; + using _Second = typename __combine_tuples<_Rem...>::__type; + using __type = typename __combine_tuples<_First, _Second>::__type; }; // Computes the result type of tuple_cat given a set of tuple-like types.