From patchwork Mon Jun 14 16:35:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1491780 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=dY4GJ1De; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G3cYW6Cg2z9sRN for ; Tue, 15 Jun 2021 02:37:18 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6DCDE3847806 for ; Mon, 14 Jun 2021 16:37:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6DCDE3847806 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1623688635; bh=qTyZR92lXwW53XMXbHlJ7eL5dT+RjbQ6RQafdzWTXvk=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=dY4GJ1DeX6giKC05CxNVWC/E+c0mXbftiCYMDZUz4cHRt/hHo0Ma0nEZzs66C7Tlo sulhIr6wrdtzhSmG+uG5w8N7vvkrm31kIPYZrofulm3m/zuyMxh9HPaY45PlhqbAwk L9O46h3tQqdgrB4YAuzmyltzLvu3nmK3Q28oVcAo= 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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 56C333892441 for ; Mon, 14 Jun 2021 16:35:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 56C333892441 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-375-aKqskNsgODumQcTqQy5w_w-1; Mon, 14 Jun 2021 12:35:53 -0400 X-MC-Unique: aKqskNsgODumQcTqQy5w_w-1 Received: by mail-qt1-f198.google.com with SMTP id a5-20020ac84d850000b029024998e61d00so7791759qtw.14 for ; Mon, 14 Jun 2021 09:35:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=qTyZR92lXwW53XMXbHlJ7eL5dT+RjbQ6RQafdzWTXvk=; b=NhedHSed4kDxL5TrHWUy1wUteE4L3aUvu9jXqs3w1LvBjYdEYvl8Ct3wjpTPqAu41L mlpk5wp/pWenSLIhIbI27TidoJK+MOrFndxrjaqNkyVWSgdfY7gwKWq1OTRVpVnwj6ca a4Zs1jJNKAv8l5TtFmcjMSx4xsIncFO0TMWri7r1GjZbk4OiIX+nY8Gg1Hc8vmPigslk wBB53O50ww409EKiQ4jf+Su4MNz5UEhPyI5wMrysEc8VDFscTj7zgOlF5hAncdX7vjr/ xsXKf/O7PSj6Zmruy8NcJiq04rg+Sqt/Z/gjclBcSVI6WlB8lCF2EoDfgv7YT1IJ2kVQ r+cw== X-Gm-Message-State: AOAM533NtdSggEzci4u1BR6Wy1Avoquxl9jXCapPhK3CYZzUygzQHoMJ mGAK5Fe/lx6nwgwPkBTllJEDPpvH6y1QsgHD6nM2p2oJcMj300lGBo0Iz6XAqoDJFtUjojBGp88 f4EG9qQYdbkqImrRbMhIuerOTPSp8YFrEVS/5OnyhJjy+gsgeWLquZJZAaXHLvhOOnZU= X-Received: by 2002:ad4:576e:: with SMTP id r14mr39692qvx.20.1623688551829; Mon, 14 Jun 2021 09:35:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwwl836phV9u4ZeYZCkBsuQET9G4VTJEKT8i/7hpDDOiDdSye+6823YT22xnKx4QVZh4eoABg== X-Received: by 2002:ad4:576e:: with SMTP id r14mr39638qvx.20.1623688551330; Mon, 14 Jun 2021 09:35:51 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id d23sm10106776qto.74.2021.06.14.09.35.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Jun 2021 09:35:50 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] libstdc++: Refine range adaptors' "simple extra args" mechanism [PR100940] Date: Mon, 14 Jun 2021 12:35:43 -0400 Message-Id: <20210614163543.502297-1-ppalka@redhat.com> X-Mailer: git-send-email 2.32.0.93.g670b81a890 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-15.3 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_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, URI_HEX autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Cc: libstdc++@gcc.gnu.org Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" The _S_has_simple_extra_args mechanism is used to simplify forwarding of range adaptor's extra arguments when perfect forwarding call wrapper semantics isn't required for correctness, on a per-adaptor basis. Both views::take and views::drop are flagged as such, but it turns out perfect forwarding semantics are needed for these adaptors in some contrived cases, e.g. when their extra argument is a move-only class that's implicitly convertible to an integral type. To fix this, we could just clear the flag for views::take/drop as with views::split, but that'd come at the cost of acceptable diagnostics for ill-formed uses of these adaptors (see PR100577). This patch instead allows adaptors to parameterize their _S_has_simple_extra_args flag according the types of the captured extra arguments, so that we could conditionally disable perfect forwarding semantics only when the types of the extra arguments permit it. We then use this finer-grained mechanism to safely disable perfect forwarding semantics for views::take/drop when the extra argument is integer-like, rather than incorrectly always disabling it. Similarly, for views::split, rather than always enabling perfect forwarding semantics we now safely disable it when the extra argument is a scalar or a view, and recover good diagnostics for these common cases. Tested on x86_64-pc-linux-gnu, does this look OK for trunk/11? PR libstdc++/100940 libstdc++-v3/ChangeLog: * include/std/ranges (__adaptor::_RangeAdaptor): Document the template form of _S_has_simple_extra_args. (__adaptor::__adaptor_has_simple_extra_args): Add _Args template parameter pack. Try to treat _S_has_simple_extra_args as a variable template parameterized by _Args. (__adaptor::_Partial): Pass _Arg/_Args to the constraint __adaptor_has_simple_extra_args. (views::_Take::_S_has_simple_extra_args): Templatize according to the type of the extra argument. (views::_Drop::_S_has_simple_extra_args): Likewise. (views::_Split::_S_has_simple_extra_args): Define. * testsuite/std/ranges/adaptors/100577.cc (test01, test02): Adjust after changes to _S_has_simple_extra_args mechanism. (test03): Define. --- libstdc++-v3/include/std/ranges | 37 +++++++++---- .../testsuite/std/ranges/adaptors/100577.cc | 55 ++++++++++++------- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 220a44e11a8..856975c6934 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -792,7 +792,9 @@ namespace views::__adaptor // // The optional static data member _Derived::_S_has_simple_extra_args should // be defined to true if the behavior of this adaptor is independent of the - // constness/value category of the extra arguments. + // constness/value category of the extra arguments. This data member could + // also be defined as a variable template parameterized by the types of the + // extra arguments. template struct _RangeAdaptor { @@ -814,9 +816,10 @@ namespace views::__adaptor concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op; // True if the behavior of the range adaptor non-closure _Adaptor is - // independent of the value category of its extra arguments. - template - concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args; + // independent of the value category of its extra arguments _Args. + template + concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args + || _Adaptor::template _S_has_simple_extra_args<_Args...>; // A range adaptor closure that represents partial application of // the range adaptor _Adaptor with arguments _Args. @@ -893,7 +896,7 @@ namespace views::__adaptor // This lets us get away with a single operator() overload, which makes // overload resolution failure diagnostics more concise. template - requires __adaptor_has_simple_extra_args<_Adaptor> + requires __adaptor_has_simple_extra_args<_Adaptor, _Args...> struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure { tuple<_Args...> _M_args; @@ -922,7 +925,7 @@ namespace views::__adaptor // A lightweight specialization of the above template for the common case // where _Adaptor accepts a single extra argument. template - requires __adaptor_has_simple_extra_args<_Adaptor> + requires __adaptor_has_simple_extra_args<_Adaptor, _Arg> struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure { _Arg _M_arg; @@ -2094,7 +2097,12 @@ namespace views::__adaptor using _RangeAdaptor<_Take>::operator(); static constexpr int _S_arity = 2; - static constexpr bool _S_has_simple_extra_args = true; + // The count argument of views::take is not always simple -- it can be + // e.g. a move-only class that's implicitly convertible to the difference + // type. But an integer-like count argument is surely simple. + template + static constexpr bool _S_has_simple_extra_args + = ranges::__detail::__is_integer_like<_Tp>; }; inline constexpr _Take take; @@ -2334,7 +2342,9 @@ namespace views::__adaptor using _RangeAdaptor<_Drop>::operator(); static constexpr int _S_arity = 2; - static constexpr bool _S_has_simple_extra_args = true; + template + static constexpr bool _S_has_simple_extra_args + = _Take::_S_has_simple_extra_args<_Tp>; }; inline constexpr _Drop drop; @@ -3212,9 +3222,14 @@ namespace views::__adaptor using _RangeAdaptor<_Split>::operator(); static constexpr int _S_arity = 2; - // The second argument of views::split is _not_ simple -- it can be a - // non-view range, the value category of which affects whether the call is - // well-formed. So we must not define _S_has_simple_extra_args to true. + // The pattern argument of views::split is not always simple -- it can be + // a non-view range, the value category of which affects whether the call + // is well-formed. But a scalar or a view pattern argument is surely + // simple. + template + static constexpr bool _S_has_simple_extra_args + = is_scalar_v<_Pattern> || (view<_Pattern> + && copy_constructible<_Pattern>); }; inline constexpr _Split split; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc index 29176c8b7b0..8ef084621f9 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc @@ -28,16 +28,18 @@ namespace views = std::ranges::views; void test01() { - // Verify all multi-argument adaptors except for views::split are denoted - // to have simple extra arguments. + // Verify adaptors are deemed to have simple extra arguments when appropriate. using views::__adaptor::__adaptor_has_simple_extra_args; - static_assert(__adaptor_has_simple_extra_args); - static_assert(__adaptor_has_simple_extra_args); - static_assert(__adaptor_has_simple_extra_args); - static_assert(__adaptor_has_simple_extra_args); - static_assert(__adaptor_has_simple_extra_args); - static_assert(__adaptor_has_simple_extra_args); - static_assert(!__adaptor_has_simple_extra_args); + using std::identity; + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(__adaptor_has_simple_extra_args); + static_assert(!__adaptor_has_simple_extra_args); // Verify all adaptor closures except for views::split(pattern) have a simple // operator(). @@ -53,15 +55,17 @@ test01() __closure_has_simple_call_op auto a08 = views::common; __closure_has_simple_call_op auto a09 = views::reverse; __closure_has_simple_call_op auto a10 = views::keys; + __closure_has_simple_call_op auto a11 = views::split(' '); // Verify composition of simple closures is simple. __closure_has_simple_call_op auto b - = (a00 | a01) | (a02 | a03) | (a04 | a05 | a06) | (a07 | a08 | a09 | a10); + = (a00 | a01) | (a02 | a03) | (a04 | a05 | a06) | (a07 | a08 | a09 | a10) | a11; - // Verify views::split is the exception. - auto a11 = views::split(' '); - static_assert(!__closure_has_simple_call_op); - static_assert(!__closure_has_simple_call_op); - static_assert(!__closure_has_simple_call_op); + // Verify views::split(non_view_range) is an exception. + extern std::string s; + auto a12 = views::split(s); + static_assert(!__closure_has_simple_call_op); + static_assert(!__closure_has_simple_call_op); + static_assert(!__closure_has_simple_call_op); } void @@ -71,18 +75,14 @@ test02() // fallback deleted overload, so when a call is ill-formed overload resolution // fails. extern int x[10]; - auto badarg = nullptr; + struct { } badarg; views::transform(badarg)(x); // { dg-error "no match" } views::filter(badarg)(x); // { dg-error "no match" } - views::take(badarg)(x); // { dg-error "no match" } - views::drop(badarg)(x); // { dg-error "no match" } views::take_while(badarg)(x); // { dg-error "no match" } views::drop_while(badarg)(x); // { dg-error "no match" } (views::transform(badarg) | views::all)(x); // { dg-error "no match" } (views::filter(badarg) | views::all)(x); // { dg-error "no match" } - (views::take(badarg) | views::all)(x); // { dg-error "no match" } - (views::drop(badarg) | views::all)(x); // { dg-error "no match" } (views::take_while(badarg) | views::all)(x); // { dg-error "no match" } (views::drop_while(badarg) | views::all)(x); // { dg-error "no match" } @@ -96,6 +96,21 @@ test02() a0(x); // { dg-error "no match" }; auto a1 = a0 | views::all; a1(x); // { dg-error "no match" } + + views::take(badarg)(x); // { dg-error "deleted" } + views::drop(badarg)(x); // { dg-error "deleted" } + (views::take(badarg) | views::all)(x); // { dg-error "deleted" } + (views::drop(badarg) | views::all)(x); // { dg-error "deleted" } +} + +void +test03() +{ + // PR libstdc++/100940 + extern int x[10]; + struct S { operator int() && { return 5; }; }; + x | std::views::take(S{}); + x | std::views::drop(S{}); } // { dg-prune-output "in requirements" } From patchwork Tue Jun 15 18:53:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1492415 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=JQ4kPnkF; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G4HYZ68DBz9s24 for ; Wed, 16 Jun 2021 04:54:41 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 583113838014 for ; Tue, 15 Jun 2021 18:54:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 583113838014 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1623783278; bh=WRzJwtWUqF/1mfJ5Vp1L/P8tvsmF5Uj7lwl1s3lNYrw=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=JQ4kPnkFuwS7qo0+ePwUYqBeGIa4rQZNQ69ffth9VSsAQX0o2suQzWd7jRCuw+NXH T+/Tq5jpeoZTkmUyIoE/tfpsdgxzcHpXdBSA271ZQOZrx6Z0st1sS28Q5BCZEzdcIN 11JR576TNEMOAeSDjJFGocwIBhUrvUK/IIibsTuk= 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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 72CFB3835406 for ; Tue, 15 Jun 2021 18:53:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 72CFB3835406 Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-341-gq9ykgP_NZGx4mDdG7e7fw-1; Tue, 15 Jun 2021 14:53:34 -0400 X-MC-Unique: gq9ykgP_NZGx4mDdG7e7fw-1 Received: by mail-qv1-f71.google.com with SMTP id 2-20020a0562140d62b02902357adaa890so206305qvs.20 for ; Tue, 15 Jun 2021 11:53:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WRzJwtWUqF/1mfJ5Vp1L/P8tvsmF5Uj7lwl1s3lNYrw=; b=kLDt90YV4yNDPEOhvufBKnsZEFZX9n8ZHdHqFlPM6zNwqZdLeD+kIw/hSO4yIwd2pK M4ECAX0iRPHZ0UsMVLDYUPW56faKTDwSI7syd4Q1coAyUlDPAevFxUigZB9c+7AnR2WX DX4/9i/hqUtVVH/psjs7mGP+ktm6tZj7tkID66bTSkXqeZpheso0yVtENZWiGK9WePY2 zfQDogi7zJUGxZ5JJvUs021gLzPPGiIrSUnO/gUJosAtarZqxMPr4Iz5v5snAKJFYpyd e+8IEV6uEJP4Ha1U/K52MRQOobdOmtJiyMQq1Csor91876FknweSmIv1aipimXgDTDPw yDjw== X-Gm-Message-State: AOAM532juFSmMkSf/OU6XEsLpwY38E4Zx5b0ib4q0vr1DHX/Smgx674D DiC8M6Caw+GQad0/Flas3nwAgl6Zi3euvEUlP+ekCJ59gfVVO8uxRJwQY82WR+nrmbdH0N0IkTO QVF03nQ+pqnT+n5E2wbA//X8PAai/fCqQZmYEwkiEUjvaIRnjWgWPnoHaP45uDYPdauI= X-Received: by 2002:a0c:f1c2:: with SMTP id u2mr6861322qvl.1.1623783213139; Tue, 15 Jun 2021 11:53:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyScAC0fOlnfq2Vwk1s98dQ10kWFqdYipt8Lj64qbT8aBuicXv+cMFZVy3KD1JFF81Wm+bciQ== X-Received: by 2002:a0c:f1c2:: with SMTP id u2mr6861302qvl.1.1623783212794; Tue, 15 Jun 2021 11:53:32 -0700 (PDT) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id o63sm9197644qke.112.2021.06.15.11.53.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 11:53:32 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/1] libstdc++: Non-triv-copyable extra args aren't simple [PR100940] Date: Tue, 15 Jun 2021 14:53:21 -0400 Message-Id: <20210615185321.1082491-1-ppalka@redhat.com> X-Mailer: git-send-email 2.32.0.93.g670b81a890 In-Reply-To: <20210614163543.502297-1-ppalka@redhat.com> References: <20210614163543.502297-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-15.2 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_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, URI_HEX autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Cc: libstdc++@gcc.gnu.org Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This force-enables perfect forwarding call wrapper semantics whenever the extra arguments of a partially applied range adaptor aren't all trivially copyable, so as to avoid incurring unnecessary copies of potentially expensive-to-copy objects (such as std::function objects) when invoking the adaptor. Tested on x86_64-pc-linux-gnu, does this look OK for trunk/11? PR libstdc++/100940 libstdc++-v3/ChangeLog: * include/std/ranges (__adaptor::__adaptor_has_simple_extra_args): Also require that the extra arguments are trivially copyable. * testsuite/std/ranges/adaptors/100577.cc (test04): New test. --- libstdc++-v3/include/std/ranges | 6 ++++-- .../testsuite/std/ranges/adaptors/100577.cc | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 856975c6934..e858df88088 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -818,8 +818,10 @@ namespace views::__adaptor // True if the behavior of the range adaptor non-closure _Adaptor is // independent of the value category of its extra arguments _Args. template - concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args - || _Adaptor::template _S_has_simple_extra_args<_Args...>; + concept __adaptor_has_simple_extra_args + = (_Adaptor::_S_has_simple_extra_args + || _Adaptor::template _S_has_simple_extra_args<_Args...>) + && (is_trivially_copyable_v<_Args> && ...); // A range adaptor closure that represents partial application of // the range adaptor _Adaptor with arguments _Args. diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc index 8ef084621f9..4040f474ad9 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc @@ -21,6 +21,7 @@ // PR libstdc++/100577 #include +#include namespace ranges = std::ranges; namespace views = std::ranges::views; @@ -113,4 +114,22 @@ test03() x | std::views::drop(S{}); } +void +test04() +{ + // Non-trivially-copyable extra arguments make a closure not simple. + using F = std::function; + static_assert(!std::is_trivially_copyable_v); + using views::__adaptor::__adaptor_has_simple_extra_args; + using views::__adaptor::__closure_has_simple_call_op; + static_assert(!__adaptor_has_simple_extra_args); + static_assert(!__adaptor_has_simple_extra_args); + static_assert(!__adaptor_has_simple_extra_args); + static_assert(!__adaptor_has_simple_extra_args); + static_assert(!__closure_has_simple_call_op()))>); + static_assert(!__closure_has_simple_call_op()))>); + static_assert(!__closure_has_simple_call_op()))>); + static_assert(!__closure_has_simple_call_op()))>); +} + // { dg-prune-output "in requirements" }