From patchwork Mon Sep 12 16:45:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1166 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5044:0:0:0:0:0 with SMTP id h4csp1964007wrt; Mon, 12 Sep 2022 09:47:40 -0700 (PDT) X-Google-Smtp-Source: AA6agR4JMcSE02DjfOaJQoTLUBF/ZtjNPqswdSEzWkdnUM+FsLem8WihKKNBW0TcCZN394mCletr X-Received: by 2002:a17:907:2cc8:b0:77d:6f62:7661 with SMTP id hg8-20020a1709072cc800b0077d6f627661mr4166796ejc.233.1663001260563; Mon, 12 Sep 2022 09:47:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663001260; cv=none; d=google.com; s=arc-20160816; b=0p7XZub4ceGnh5hdNwzS2GjzjCUqStxFrm/uoSdNSw/9c+MW3vIiog8wHBQXzwBi69 8BYi9CPnrN55vtoNQQe974s7uXWALtmqsxmaf7jTSa9xZDuYH4d/nhoy2w13SVk7YT4o tb0JNhZUvohiEIhzQOVYvedmaaa3vJl0zoSXxyAxV5jkiE1Njf3+MBHfDUaqKvx8/Pmx w6Noz/RN1nH6r0D9jDLmgjk5hzLXFYC4EJwQDV+5JQr3EGme0VamsxVVxA1V/bf01F91 Bqg8hfx6hLOLT/+53HBQPeOrMJPMpcyLeErs4fkgfIj2HodV08Gtn1bLBL7MI7IO0+P2 drRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=YiVfJJKyMFRTPb30HBSDZspjGAT8X/f0ELDYdIUceD0=; b=GSU9QjDnSlJNhNPQzFHS8+jFRVj3Lxy1SOvWY7xgrvb7IFNeKVIFRIbGG9BK2UcUe1 EpzEelj5s/nW8B9UAojFTDsFoYKf+aLsnXtmz1+JDiLuyms2GkDEy3PCms+TInMK/sdc gy8SV/CEQf44/I/aHFOnSNVOQe10E51rhq+5S2llQPaOeAr0Vd0Fnd5v4UKD8+5GiigW csOr1SG00BN/zmMgutud0GYZf0v5+0gZj+jFucc6YsxIfJwwcqhwZS/Y9FWNyLa5NXhm XbJnMFzABqltnwp3JNUUukOFGJz1/t2m3HkjAtKiUf4EPoKzaoAWELKUKbxbH2dZxBjV NwMA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=h9VqeiG0; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id cw18-20020a170906479200b0077f77eddc25si863199ejc.176.2022.09.12.09.47.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:47:40 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=h9VqeiG0; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EB064393BC37 for ; Mon, 12 Sep 2022 16:46:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EB064393BC37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663001191; bh=YiVfJJKyMFRTPb30HBSDZspjGAT8X/f0ELDYdIUceD0=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=h9VqeiG0R1v9clktTPWdckCRvv5fFAJr4X5UcIQqr2aCresWy+IAfHJ7Czzn7DL/K U+VcTP9fPnTQ1ae7Oy4VBUuzeZf1EZ5VD9aXpDgiAFMqYQHx/YVM1+U1pU9H1wBNpx +xtzsQjEF0KefcT1qv89dIJXuOVVe+aXtmMxlJ0I= 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 ESMTPS id 9B1EF3898C6A for ; Mon, 12 Sep 2022 16:45:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9B1EF3898C6A Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-13-4xTpAzpfMSyqsz8BzKnvhw-1; Mon, 12 Sep 2022 12:45:40 -0400 X-MC-Unique: 4xTpAzpfMSyqsz8BzKnvhw-1 Received: by mail-qk1-f199.google.com with SMTP id bk21-20020a05620a1a1500b006be9f844c59so7807613qkb.9 for ; Mon, 12 Sep 2022 09:45:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date; bh=YiVfJJKyMFRTPb30HBSDZspjGAT8X/f0ELDYdIUceD0=; b=K1+c3CvEw8B0emDgcrR/S9QvKHwHKXcfeRqL1s9/6J5A9dcpKCE0c9LMt+QVnN7rzS wes0cKEsrTmwdp0Pe1iyJJylwqLHERP7pDrzCIXKGZGaBrUSUN2xqIgYFD/qnlOpMf+h lF6kfy1Muz3iJmMrKlmU8vScwKGolw8k1TdZGGhx1Aka9E5/eIdxm9p2YNF4Xdi0AEn3 rGg0rR5eL2OoO8/zE2bS5POGqGuuKt8yDSzsBfAQolNL5BRTmXwcfpUTi0J+wSgA9JRV X75PLwt1OaT5sWTttQ8f0jc3Bdry/if/A5Lg+nvojuvAuQ9NhJbjSBjP7C5Wf+RVIpbR 21zQ== X-Gm-Message-State: ACgBeo0zmALIydNYCC6Zgb60echtPtocrV4SXaPqZj2FyL/r8Q6IPjD0 V7ZB9jfX5a/ng5nKRwwnkyAtgCRgkRZc8Y6qGDQT50QoZwK2wL8ov7fsonx1pRvOIlaHc1zj4pZ cYgC92mFR9M7D3D6mrfuhA09PEMKW8fg9A1ydT6maX07dpALDHj4R4m07KwXcw4qEdQ4= X-Received: by 2002:a05:622a:1650:b0:344:6ec4:739 with SMTP id y16-20020a05622a165000b003446ec40739mr24157481qtj.515.1663001140415; Mon, 12 Sep 2022 09:45:40 -0700 (PDT) X-Received: by 2002:a05:622a:1650:b0:344:6ec4:739 with SMTP id y16-20020a05622a165000b003446ec40739mr24157454qtj.515.1663001140158; Mon, 12 Sep 2022 09:45:40 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id 17-20020ac85651000000b0035ba48c032asm6667350qtt.25.2022.09.12.09.45.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:45:39 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/4] libstdc++: Add already-accepted testcase [PR106320] Date: Mon, 12 Sep 2022 12:45:28 -0400 Message-Id: <20220912164531.1742034-1-ppalka@redhat.com> X-Mailer: git-send-email 2.37.3.542.gdd3f6c4cae MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.7 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, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=unavailable 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.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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1743783210095236228?= X-GMAIL-MSGID: =?utf-8?q?1743783210095236228?= Although PR106320 only affected the 10 and 11 branches, and the testcase from there was already correctly accepted on trunk and the 12 branch, we should also add the testcase to 12/trunk for inter-branch consistency. Tested on x86_64-pc-linux-gnu, does this look OK for trunk/12? PR libstdc++/106320 libstdc++-v3/ChangeLog: * testsuite/std/ranges/adaptors/join.cc (test13): New test. --- libstdc++-v3/testsuite/std/ranges/adaptors/join.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc index 8986f718229..530ab6663b5 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc @@ -205,6 +205,18 @@ test12() }(); } +void +test13() +{ + // PR libstdc++/106320 + auto l = std::views::transform([](auto x) { + return x | std::views::transform([i=0](auto y) { + return y; + }); + }); + std::vector> v{{5, 6, 7}}; + v | l | std::views::join; +} int main() { @@ -220,4 +232,5 @@ main() test10(); test11(); test12(); + test13(); } From patchwork Mon Sep 12 16:45:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1168 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5044:0:0:0:0:0 with SMTP id h4csp1964535wrt; Mon, 12 Sep 2022 09:49:03 -0700 (PDT) X-Google-Smtp-Source: AA6agR6O9HQt6ry7tsMKJd0ZrI47WewtPYgH2Dh6peKzq197kvi4v2Trelav9YPJu4dTYQcZnKW+ X-Received: by 2002:a17:907:75c1:b0:72f:248d:5259 with SMTP id jl1-20020a17090775c100b0072f248d5259mr19789169ejc.227.1663001343497; Mon, 12 Sep 2022 09:49:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663001343; cv=none; d=google.com; s=arc-20160816; b=Hw3ukDVuflpAMbA3Vv1c413AWGHwGBaE040g+RGJUwHA2nsNFW349vYcOEqP0ahYwJ UctINSa55OjBYAAtrNLbu+G8tZvlaMVCPXChri8FQFMBibkR1J9JqKgY7Evvk9MG61ql c1xYLDkv5VVHzHIOgfMGZI/IZdPjZHZtHVx1e2jBNOQUDbLTLAj+OUWZfL2RjGt/oidH EpvyVeFaAFEtlJvTWCgwpX0yOZe1E24oBxfNRIEU9NRKG4rsSsv7W2HcfNWVqrQc4XbK wEYK90L5tFONg5ooDUOt6amgKwVbZzDwf7yFXBvnnyXY49Bfc+sVSUBBWSBxFxLT3E1f 7cfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=x4ZYrG2d13Kk/6s+RjiiA6vGLL0TbNaWFHnV4B78tfo=; b=mFkRkAldaRoBQdtkasgYSs7A9gM8at6F918v9yE97J9f2Pxo/u3eXs/B+JkceOgsEX bDX/yNFz25PROvg423DVyr6u9TXliIxLSRzPbfXrsppqpZM0NxIzVCdLh1jeod5P0WQx 2utYb2xik3B6bzy2bvi49UBhdoQV5oRTsYu6ZxjJ3Bnz8F5/sEp4uR62tWd3rzpndnJu DNynpzDHCIVGUmGeTDxfhAjZH3HcTUo1iEx7QQ2VZOPRUvntV0QGRCPFRh+uqod1x7Q8 +8c5jodQQ7NNQY7QvAGG+R2phyFgH7o5TacQEaq4iblspw48o+MupIIK2fQ24p3rxrEX HMkA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=GeVx1Ydx; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id l26-20020a50d6da000000b00445d00730b3si7677999edj.416.2022.09.12.09.49.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:49:03 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=GeVx1Ydx; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 744AF393BA74 for ; Mon, 12 Sep 2022 16:47:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 744AF393BA74 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663001249; bh=x4ZYrG2d13Kk/6s+RjiiA6vGLL0TbNaWFHnV4B78tfo=; 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=GeVx1YdxY8NEjCWN0t99Snvab9XTQ8feTC+IFSyzK14Vh4/fm69zqp8sfkoq2vU8+ Qgy0KcKRIx9k1oyHwT8/hE2II75Pk2fzC5cJ9NhX5u/RLKYu6ctSD9s+09J5D4pAsi SJF/b2zKCtDRdERyxnseF6yZsTRrBzPifd0/mYOQ= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 8A01A38A8152 for ; Mon, 12 Sep 2022 16:45:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8A01A38A8152 Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-192-widRYh8AOSWUyUuQ_KjxvQ-1; Mon, 12 Sep 2022 12:45:42 -0400 X-MC-Unique: widRYh8AOSWUyUuQ_KjxvQ-1 Received: by mail-qv1-f69.google.com with SMTP id ec8-20020ad44e68000000b004aab01f3eaaso6125772qvb.4 for ; Mon, 12 Sep 2022 09:45:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=x4ZYrG2d13Kk/6s+RjiiA6vGLL0TbNaWFHnV4B78tfo=; b=17ln7Kq1OiivinBHkn2fyj0P1NezbmOHW0mNiQ7RpRXifO/08lIuuZB5NL1lOIEmDT VNUp0DH60SCWgJYXGM0NbtDE4kWVFV05fT+QP5Hk2SqmSvaRnsyWV+0VdZ6lZEofUmF0 Ny9rQ+rbB/qBDAaOqmWkGZMAcEj9E5/ib9SkKGqhirchKLS4InT16y1l0iTGq7SZjggR dkmjMfXO5Ntk03gHkeI1dFGlPWMhjYNqRpkYvWivxgUJwqEobPtb5BiN0e9o53l03iH+ esJIEJaTv9K8MtOOqw5ie34LEkpiPcBU0e/VzuSJYZmITrczacMBdDbH8Is5xbrMZ6H1 0rXg== X-Gm-Message-State: ACgBeo0tzbiuekaSHfddaD5MoFZpTeUNGgo4VccYIim3PNCuxEbJMbYl gZy6HIbCLuPlGXhDFFWvpi40gahpuuMUChXI+c+oT25YUzrWM/mTDoJ7hZtP4tykhPoQC0NugsV +tB42M+FwpGOS5BrgLdWnXZWBzFVHu0FC6gQhElVTXsPwZnef/nXnXuUoSG1BIoR0DBE= X-Received: by 2002:a05:620a:124f:b0:6cd:ef55:544c with SMTP id a15-20020a05620a124f00b006cdef55544cmr9030247qkl.158.1663001141550; Mon, 12 Sep 2022 09:45:41 -0700 (PDT) X-Received: by 2002:a05:620a:124f:b0:6cd:ef55:544c with SMTP id a15-20020a05620a124f00b006cdef55544cmr9030231qkl.158.1663001141230; Mon, 12 Sep 2022 09:45:41 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id 17-20020ac85651000000b0035ba48c032asm6667350qtt.25.2022.09.12.09.45.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:45:40 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/4] libstdc++: Implement LWG 3569 changes to join_view::_Iterator Date: Mon, 12 Sep 2022 12:45:29 -0400 Message-Id: <20220912164531.1742034-2-ppalka@redhat.com> X-Mailer: git-send-email 2.37.3.542.gdd3f6c4cae In-Reply-To: <20220912164531.1742034-1-ppalka@redhat.com> References: <20220912164531.1742034-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.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, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1743783296811191677?= X-GMAIL-MSGID: =?utf-8?q?1743783296811191677?= Tested on x86_64-pc-linux-gnu, does this look OK for trunk only? libstdc++-v3/ChangeLog: * include/std/ranges (join_view::_Iterator::_M_satisfy): Adjust resetting _M_inner as per LWG 3569. (join_view::_Iterator::_M_inner): Wrap in std::optional as per LWG 3569. (join_view::_Iterator::_Iterator): Relax constraints as per LWG 3569. (join_view::_Iterator::operator*): Adjust as per LWG 3569. (join_view::_Iterator::operator->): Likewise. (join_view::_Iterator::operator++): Likewise. (join_view::_Iterator::operator--): Likewise. (join_view::_Iterator::iter_move): Likewise. (join_view::_Iterator::iter_swap): Likewise. * testsuite/std/ranges/adaptor/join.cc (test14): New test. --- libstdc++-v3/include/std/ranges | 28 +++++++++---------- .../testsuite/std/ranges/adaptors/join.cc | 17 +++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 20eb4e82ac8..6297ce7cee3 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -2746,7 +2746,7 @@ namespace views::__adaptor } if constexpr (_S_ref_is_glvalue) - _M_inner = _Inner_iter(); + _M_inner.reset(); } static constexpr auto @@ -2769,7 +2769,7 @@ namespace views::__adaptor using _Inner_iter = join_view::_Inner_iter<_Const>; _Outer_iter _M_outer = _Outer_iter(); - _Inner_iter _M_inner = _Inner_iter(); + optional<_Inner_iter> _M_inner; _Parent* _M_parent = nullptr; public: @@ -2780,9 +2780,7 @@ namespace views::__adaptor = common_type_t, range_difference_t>>; - _Iterator() requires (default_initializable<_Outer_iter> - && default_initializable<_Inner_iter>) - = default; + _Iterator() requires default_initializable<_Outer_iter> = default; constexpr _Iterator(_Parent* __parent, _Outer_iter __outer) @@ -2801,7 +2799,7 @@ namespace views::__adaptor constexpr decltype(auto) operator*() const - { return *_M_inner; } + { return **_M_inner; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3500. join_view::iterator::operator->() is bogus @@ -2809,7 +2807,7 @@ namespace views::__adaptor operator->() const requires __detail::__has_arrow<_Inner_iter> && copyable<_Inner_iter> - { return _M_inner; } + { return *_M_inner; } constexpr _Iterator& operator++() @@ -2820,7 +2818,7 @@ namespace views::__adaptor else return *_M_parent->_M_inner; }(); - if (++_M_inner == ranges::end(__inner_range)) + if (++*_M_inner == ranges::end(__inner_range)) { ++_M_outer; _M_satisfy(); @@ -2850,9 +2848,9 @@ namespace views::__adaptor { if (_M_outer == ranges::end(_M_parent->_M_base)) _M_inner = ranges::end(*--_M_outer); - while (_M_inner == ranges::begin(*_M_outer)) - _M_inner = ranges::end(*--_M_outer); - --_M_inner; + while (*_M_inner == ranges::begin(*_M_outer)) + *_M_inner = ranges::end(*--_M_outer); + --*_M_inner; return *this; } @@ -2879,14 +2877,14 @@ namespace views::__adaptor friend constexpr decltype(auto) iter_move(const _Iterator& __i) - noexcept(noexcept(ranges::iter_move(__i._M_inner))) - { return ranges::iter_move(__i._M_inner); } + noexcept(noexcept(ranges::iter_move(*__i._M_inner))) + { return ranges::iter_move(*__i._M_inner); } friend constexpr void iter_swap(const _Iterator& __x, const _Iterator& __y) - noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner))) + noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner))) requires indirectly_swappable<_Inner_iter> - { return ranges::iter_swap(__x._M_inner, __y._M_inner); } + { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); } friend _Iterator; template friend struct _Sentinel; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc index 530ab6663b5..afc11d4bd7a 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -217,6 +218,21 @@ test13() std::vector> v{{5, 6, 7}}; v | l | std::views::join; } + +void +test14() +{ + // LWG 3569: join_view fails to support ranges of ranges with + // non-default_initializable iterators + auto ss = std::istringstream{"1 2 3"}; + auto v = views::single(views::istream(ss)); + using inner = ranges::range_reference_t; + static_assert(ranges::input_range + && !ranges::forward_range + && !std::default_initializable>); + VERIFY( ranges::equal(v | views::join, (int[]){1, 2, 3}) ); +} + int main() { @@ -233,4 +249,5 @@ main() test11(); test12(); test13(); + test14(); } From patchwork Mon Sep 12 16:45:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1167 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5044:0:0:0:0:0 with SMTP id h4csp1964086wrt; Mon, 12 Sep 2022 09:47:52 -0700 (PDT) X-Google-Smtp-Source: AA6agR4RnRxPbKy7wZEaJNYRbCD0JW2wgk+CGZJ2LbyaYEyk9vZWCnlkqFV19u7uwzsFcmTyEvJu X-Received: by 2002:a17:907:802:b0:73d:c710:943e with SMTP id wv2-20020a170907080200b0073dc710943emr19068950ejb.214.1663001272628; Mon, 12 Sep 2022 09:47:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663001272; cv=none; d=google.com; s=arc-20160816; b=o4wL3E7v9JeGb++i7YFhlhQHX5oeuO1S34rl6+Sy2bCzpkjALxk/SMKJ5fT0DHBwa5 /pB9nOGCfOUCzrrg8cheVtVeZhIo1i95pSj7+jeAxj2fY4Ecmb1MnsEQmw6cF1Uln9RF GFkWGnMfr9m6bSM+0MP2SOHCyUb1hUNYi4OtfWz3anotMZpKRQUCudwHXBIzj+yCp/0j 8wgA7dqU8lCFXAZjWahfw5kT5EqRzPxTmgvnDSSKPnx54/a4TMiP2WWuouu+m5YCgYHe h1DJGMvCoFh7yuz4DAmj7bXEmvuNVRYS54kkJeczsdFq8qtHnJtHRSWBp8vkvAFbMWau tj1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=q4fv7jvzYnJ4FhYE1dAxfiEnUn/zQ17yyUxwt5vlDVw=; b=xrBEgccMhel0DPBgc9u71cnyKe5CSdqnVWD+VdUZbhUatOuuMeIpK5L0cmiKFeALHA yN3Eq2cghSzi33Qmm978AcC47elFSnMEXZL/bHnfcaWTZSVQR0V4MoBQJhc4gC2RKPeu ZGt8HaV6T19bFKbJgNnkW/EGMXIrXDa1oHbXb0Y+Uqk5EIZWM0fhUFLR2bpoZiKVYPP/ uKJjd2ytycFf1rK4wAKn38CtzJT/NtnM9CITjG1viB1M3AKVc0yDVHE8cG51Y159EQCV lDO9IdRSt5QLBp+6DaxOd6Y8FqTwiJxOv2qbrAejJRy4OpXB0+xK8qMpKAex0jV5zOxH 6rTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kT9qUFnI; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id x2-20020a05640225c200b0044e8ae24f6bsi5824857edb.236.2022.09.12.09.47.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:47:52 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kT9qUFnI; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4EBD4394B031 for ; Mon, 12 Sep 2022 16:46:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4EBD4394B031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663001196; bh=q4fv7jvzYnJ4FhYE1dAxfiEnUn/zQ17yyUxwt5vlDVw=; 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=kT9qUFnI8a5/5gnepFrrznyMcolgX9Xn5tC0e97j6UrGbnmDK0xREMCDWljLTScYd dTGsvWTJhgNnsGFHf5jPpZNVkfy+V3Ng7CVgfgIj/iL6gHJrjj/5nMzwIzYB2GUi/0 zUmpXjofS1jKNSZe3tMFPOnUT2+ppIkjhlXYzVmo= 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 ESMTPS id 8E9A938A908C for ; Mon, 12 Sep 2022 16:45:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8E9A938A908C Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-383-BsJ8ZIZUMNGUvB9_pnMc-A-1; Mon, 12 Sep 2022 12:45:43 -0400 X-MC-Unique: BsJ8ZIZUMNGUvB9_pnMc-A-1 Received: by mail-qk1-f198.google.com with SMTP id bj2-20020a05620a190200b006bba055ab6eso7826696qkb.12 for ; Mon, 12 Sep 2022 09:45:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=q4fv7jvzYnJ4FhYE1dAxfiEnUn/zQ17yyUxwt5vlDVw=; b=JegfUr+p5mtBCpa5u2s/mu+h3HGhnT+yFtWQh7g9tz1agtMUaPX+7ISTjTkeyH6duu aH5h/JQEoZsJ6VVPa9cyRcwagzaEuxUrpgO1uun1eGQSsS68idLpKkzS4jTrluxkZy7K G/SJAEYH73JBUZypFetMgXzZRCfRRJVJHMy/vhwJCA2Q1qWLk5i7qS6Uae3vsaoGoJNZ xcugtlWpdpc90+gSXxVKQb1EGcQnLjd/CZ2O7zqNqSJ2yNRXZBjxWtfWtniiqX34dr8T z9y7VGNzYWPeW3wdtn10vbaXRiOKILmn070MyCIi2SjY1s+wmJf5V/Sthpq5V0j2N8xw CW1g== X-Gm-Message-State: ACgBeo1MUz3xG0P7xv4wxrJFo3w+Bi9W0/gXh/AzYR1h0HC5CT43iJx5 w3eITi7VHc67wD84KQKhh7apzzPVvS/Sifja5aoVm+vimfHwT6JUv6BF+nHcsRgaMyalUafsTcC cLO1kIsL0hNdPVZ++FFOII15uU/AGJVy8JtrOGgSTvsQeRbYoF9jALCuPxluzvSgm0Ok= X-Received: by 2002:a05:620a:4409:b0:6bb:beeb:215e with SMTP id v9-20020a05620a440900b006bbbeeb215emr20257305qkp.414.1663001142983; Mon, 12 Sep 2022 09:45:42 -0700 (PDT) X-Received: by 2002:a05:620a:4409:b0:6bb:beeb:215e with SMTP id v9-20020a05620a440900b006bbbeeb215emr20257272qkp.414.1663001142530; Mon, 12 Sep 2022 09:45:42 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id 17-20020ac85651000000b0035ba48c032asm6667350qtt.25.2022.09.12.09.45.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:45:42 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 3/4] libstdc++: Implement ranges::chunk_view from P2442R1 Date: Mon, 12 Sep 2022 12:45:30 -0400 Message-Id: <20220912164531.1742034-3-ppalka@redhat.com> X-Mailer: git-send-email 2.37.3.542.gdd3f6c4cae In-Reply-To: <20220912164531.1742034-1-ppalka@redhat.com> References: <20220912164531.1742034-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1743783222243516628?= X-GMAIL-MSGID: =?utf-8?q?1743783222243516628?= This also implements the LWG 3707, 3710 and 3712 changes to chunk_view. libstdc++-v3/ChangeLog: * include/std/ranges (__detail::__div_ceil): Define. (chunk_view): Define. (chunk_view::_OuterIter): Define. (chunk_view::_OuterIter::value_type): Define. (chunk_view::_InnerIter): Define. (chunk_view<_Vp>): Define partial specialization for forward ranges. (enable_borrowed_range): Define. (chunk_view<_Vp>::_Iterator): Define. (views::__detail::__can_chunk_view): Define. (views::_Chunk, views::chunk): Define. * testsuite/std/ranges/adaptors/chunk/1.cc: New test. --- libstdc++-v3/include/std/ranges | 538 ++++++++++++++++++ .../testsuite/std/ranges/adaptors/chunk/1.cc | 80 +++ 2 files changed, 618 insertions(+) create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 6297ce7cee3..7533b60c1d6 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -5776,6 +5776,544 @@ namespace views::__adaptor inline constexpr auto pairwise_transform = adjacent_transform<2>; } + + namespace __detail + { + template + constexpr _Tp __div_ceil(_Tp __num, _Tp __denom) + { + _Tp __r = __num / __denom; + if (__num % __denom) + ++__r; + return __r; + } + } + + template + requires input_range<_Vp> + class chunk_view : public view_interface> + { + _Vp _M_base; + range_difference_t<_Vp> _M_n; + range_difference_t<_Vp> _M_remainder = 0; + __detail::__non_propagating_cache> _M_current; + + class _OuterIter; + class _InnerIter; + + public: + constexpr explicit + chunk_view(_Vp __base, range_difference_t<_Vp> __n) + : _M_base(std::move(__base)), _M_n(__n) + { __glibcxx_assert(__n >= 0); } + + constexpr _Vp + base() const & requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + { return std::move(_M_base); } + + constexpr _OuterIter + begin() + { + _M_current = ranges::begin(_M_base); + _M_remainder = _M_n; + return _OuterIter(*this); + } + + constexpr default_sentinel_t + end() const noexcept + { return default_sentinel; } + + constexpr auto + size() requires sized_range<_Vp> + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + + constexpr auto + size() const requires sized_range + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + }; + + template + chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view>; + + template + requires input_range<_Vp> + class chunk_view<_Vp>::_OuterIter + { + chunk_view* _M_parent; + + constexpr explicit + _OuterIter(chunk_view& __parent) + : _M_parent(std::__addressof(__parent)) + { } + + friend chunk_view; + + public: + using iterator_concept = input_iterator_tag; + using difference_type = range_difference_t<_Vp>; + + struct value_type; + + _OuterIter(_OuterIter&&) = default; + _OuterIter& operator=(_OuterIter&&) = default; + + constexpr value_type + operator*() const + { + __glibcxx_assert(*this != default_sentinel); + return value_type(*_M_parent); + } + + constexpr _OuterIter& + operator++() + { + __glibcxx_assert(*this != default_sentinel); + ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder, + ranges::end(_M_parent->_M_base)); + _M_parent->_M_remainder = _M_parent->_M_n; + return *this; + } + + constexpr void + operator++(int) + { ++*this; } + + friend constexpr bool + operator==(const _OuterIter& __x, default_sentinel_t) + { + return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base) + && __x._M_parent->_M_remainder != 0; + } + + friend constexpr difference_type + operator-(default_sentinel_t, const _OuterIter& __x) + requires sized_sentinel_for, iterator_t<_Vp>> + { + const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current; + + if (__dist < __x._M_parent->_M_remainder) + return __dist == 0 ? 0 : 1; + + return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder, + __x._M_parent->_M_n); + } + + friend constexpr difference_type + operator-(const _OuterIter& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Vp>> + { return -(__y - __x); } + }; + + template + requires input_range<_Vp> + struct chunk_view<_Vp>::_OuterIter::value_type : view_interface + { + private: + chunk_view* _M_parent; + + constexpr explicit + value_type(chunk_view& __parent) + : _M_parent(std::__addressof(__parent)) + { } + + friend _OuterIter; + + public: + constexpr _InnerIter + begin() const noexcept + { return _InnerIter(*_M_parent); } + + constexpr default_sentinel_t + end() const noexcept + { return default_sentinel; } + + constexpr auto + size() const + requires sized_sentinel_for, iterator_t<_Vp>> + { + return __detail::__to_unsigned_like + (ranges::min(_M_parent->_M_remainder, + ranges::end(_M_parent->_M_base) - *_M_parent->_M_current)); + } + }; + + template + requires input_range<_Vp> + class chunk_view<_Vp>::_InnerIter + { + chunk_view* _M_parent; + + constexpr explicit + _InnerIter(chunk_view& __parent) noexcept + : _M_parent(std::__addressof(__parent)) + { } + + friend _OuterIter::value_type; + + public: + using iterator_concept = input_iterator_tag; + using difference_type = range_difference_t<_Vp>; + using value_type = range_value_t<_Vp>; + + _InnerIter(_InnerIter&&) = default; + _InnerIter& operator=(_InnerIter&&) = default; + + constexpr const iterator_t<_Vp>& + base() const & + { return *_M_parent->_M_current; } + + constexpr range_reference_t<_Vp> + operator*() const + { + __glibcxx_assert(*this != default_sentinel); + return **_M_parent->_M_current; + } + + constexpr _InnerIter& + operator++() + { + __glibcxx_assert(*this != default_sentinel); + ++*_M_parent->_M_current; + if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base)) + _M_parent->_M_remainder = 0; + else + --_M_parent->_M_remainder; + return *this; + } + + constexpr void + operator++(int) + { ++*this; } + + friend constexpr bool + operator==(const _InnerIter& __x, default_sentinel_t) + { return __x._M_parent->_M_remainder == 0; } + + friend constexpr difference_type + operator-(default_sentinel_t, const _InnerIter& __x) + requires sized_sentinel_for, iterator_t<_Vp>> + { + return ranges::min(__x._M_parent->_M_remainder, + ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current); + } + + friend constexpr difference_type + operator-(const _InnerIter& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Vp>> + { return -(__y - __x); } + }; + + template + requires forward_range<_Vp> + class chunk_view<_Vp> : public view_interface> + { + _Vp _M_base; + range_difference_t<_Vp> _M_n; + template class _Iterator; + + public: + constexpr explicit + chunk_view(_Vp __base, range_difference_t<_Vp> __n) + : _M_base(std::move(__base)), _M_n(__n) + { __glibcxx_assert(__n > 0); } + + constexpr _Vp + base() const & requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + { return std::move(_M_base); } + + constexpr auto + begin() requires (!__detail::__simple_view<_Vp>) + { return _Iterator(this, ranges::begin(_M_base)); } + + constexpr auto + begin() const requires forward_range + { return _Iterator(this, ranges::begin(_M_base)); } + + constexpr auto + end() requires (!__detail::__simple_view<_Vp>) + { + if constexpr (common_range<_Vp> && sized_range<_Vp>) + { + auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n; + return _Iterator(this, ranges::end(_M_base), __missing); + } + else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>) + return _Iterator(this, ranges::end(_M_base)); + else + return default_sentinel; + } + + constexpr auto + end() const requires forward_range + { + if constexpr (common_range && sized_range) + { + auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n; + return _Iterator(this, ranges::end(_M_base), __missing); + } + else if constexpr (common_range && !bidirectional_range) + return _Iterator(this, ranges::end(_M_base)); + else + return default_sentinel; + } + + constexpr auto + size() requires sized_range<_Vp> + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + + constexpr auto + size() const requires sized_range + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + }; + + template + inline constexpr bool enable_borrowed_range> + = forward_range<_Vp> && enable_borrowed_range<_Vp>; + + template + requires forward_range<_Vp> + template + class chunk_view<_Vp>::_Iterator + { + using _Parent = __detail::__maybe_const_t<_Const, chunk_view>; + using _Base = __detail::__maybe_const_t<_Const, _Vp>; + + iterator_t<_Base> _M_current = iterator_t<_Base>(); + sentinel_t<_Base> _M_end = sentinel_t<_Base>(); + range_difference_t<_Base> _M_n = 0; + range_difference_t<_Base> _M_missing = 0; + + constexpr + _Iterator(_Parent* __parent, iterator_t<_Base> __current, + range_difference_t<_Base> __missing = 0) + : _M_current(__current), _M_end(ranges::end(__parent->_M_base)), + _M_n(__parent->_M_n), _M_missing(__missing) + { } + + static auto + _S_iter_cat() + { + if constexpr (random_access_range<_Base>) + return random_access_iterator_tag{}; + else if constexpr (bidirectional_range<_Base>) + return bidirectional_iterator_tag{}; + else + return forward_iterator_tag{}; + } + + friend chunk_view; + + public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(_S_iter_cat()); + using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n)); + using difference_type = range_difference_t<_Base>; + + _Iterator() = default; + + constexpr _Iterator(_Iterator __i) + requires _Const + && convertible_to, iterator_t<_Base>> + && convertible_to, sentinel_t<_Base>> + : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)), + _M_n(__i._M_n), _M_missing(__i._M_missing) + { } + + constexpr iterator_t<_Base> + base() const + { return _M_current; } + + constexpr value_type + operator*() const + { + __glibcxx_assert(_M_current != _M_end); + return views::take(subrange(_M_current, _M_end), _M_n); + } + + constexpr _Iterator& + operator++() + { + __glibcxx_assert(_M_current != _M_end); + _M_missing = ranges::advance(_M_current, _M_n, _M_end); + return *this; + } + + constexpr _Iterator + operator++(int) + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr _Iterator& + operator--() requires bidirectional_range<_Base> + { + ranges::advance(_M_current, _M_missing - _M_n); + _M_missing = 0; + return *this; + } + + constexpr _Iterator + operator--(int) requires bidirectional_range<_Base> + { + auto __tmp = *this; + --*this; + return __tmp; + } + + constexpr _Iterator& + operator+=(difference_type __x) + requires random_access_range<_Base> + { + if (__x > 0) + { + __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1)); + _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end); + } + else if (__x < 0) + { + ranges::advance(_M_current, _M_n * __x + _M_missing); + _M_missing = 0; + } + return *this; + } + + constexpr _Iterator& + operator-=(difference_type __x) + requires random_access_range<_Base> + { return *this += -__x; } + + constexpr value_type + operator[](difference_type __n) const + requires random_access_range<_Base> + { return *(*this + __n); } + + friend constexpr bool + operator==(const _Iterator& __x, const _Iterator& __y) + { return __x._M_current == __y._M_current; } + + friend constexpr bool + operator==(const _Iterator& __x, default_sentinel_t) + { return __x._M_current == __x._M_end; } + + friend constexpr bool + operator<(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return __x._M_current > __y._M_current; } + + friend constexpr bool + operator>(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return __y < __x; } + + friend constexpr bool + operator<=(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return !(__y < __x); } + + friend constexpr bool + operator>=(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return !(__x < __y); } + + friend constexpr auto + operator<=>(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + && three_way_comparable> + { return __x._M_current <=> __y._M_current; } + + friend constexpr _Iterator + operator+(const _Iterator& __i, difference_type __n) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __n; + return __r; + } + + friend constexpr _Iterator + operator+(difference_type __n, const _Iterator& __i) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __n; + return __r; + } + + friend constexpr _Iterator + operator-(const _Iterator& __i, difference_type __n) + requires random_access_range<_Base> + { + auto __r = __i; + __r -= __n; + return __r; + } + + friend constexpr difference_type + operator-(const _Iterator& __x, const _Iterator& __y) + requires sized_sentinel_for, iterator_t<_Base>> + { + return (__x._M_current - __y._M_current + + __x._M_missing - __y._M_missing) / __x._M_n; + } + + friend constexpr difference_type + operator-(default_sentinel_t __y, const _Iterator& __x) + requires sized_sentinel_for, iterator_t<_Base>> + { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); } + + friend constexpr difference_type + operator-(const _Iterator& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Base>> + { return -(__y - __x); } + }; + + namespace views + { + namespace __detail + { + template + concept __can_chunk_view + = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); }; + } + + struct _Chunk : __adaptor::_RangeAdaptor<_Chunk> + { + template> + requires __detail::__can_chunk_view<_Range, _Dp> + constexpr auto + operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const + { return chunk_view(std::forward<_Range>(__r), __n); } + + using __adaptor::_RangeAdaptor<_Chunk>::operator(); + static constexpr int _S_arity = 2; + static constexpr bool _S_has_simple_extra_args = true; + }; + + inline constexpr _Chunk chunk; + } + #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc new file mode 100644 index 00000000000..125c88ef853 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include +#include +#include + +namespace ranges = std::ranges; +namespace views = std::views; + +constexpr bool +test01() +{ + int x[] = {1, 2, 3, 4, 5}; + + auto v2 = x | views::chunk(2); + const auto i0 = v2.begin(), i1 = v2.begin() + 1; + VERIFY( i0 + 1 - 1 == i0 ); + VERIFY( i0 < i1 ); + VERIFY( i1 < v2.end() ); + VERIFY( i1 - i0 == 1 ); + VERIFY( i0 - i1 == -1 ); + VERIFY( v2.end() - i1 == 2 ); + VERIFY( i1 - v2.end() == -2 ); + auto i2 = v2.begin(); + i2 += 2; + i2 -= -1; + VERIFY( i2 == v2.end() ); + VERIFY( ranges::size(v2) == 3 ); + VERIFY( ranges::equal(v2, (std::initializer_list[]){{1, 2}, {3, 4}, {5}}, + ranges::equal) ); + + auto v1 = x | views::chunk(1); + VERIFY( ranges::size(v1) == ranges::size(x) ); + for (auto [r, n] : views::zip(v1, x)) + { + VERIFY( ranges::size(r) == 1 ); + VERIFY( *r.begin() == n ); + } + + auto v5 = x | views::chunk(5); + VERIFY( ranges::size(v5) == 1 ); + VERIFY( ranges::equal(v5[0], (int[]){1, 2, 3, 4, 5}) ); + + auto v10 = x | views::chunk(10); + VERIFY( ranges::size(v10) == 1 ); + VERIFY( ranges::equal(v10[0], (int[]){1, 2, 3, 4, 5}) ); + + return true; +} + +template +void +test02() +{ + int x[] = {1, 2, 3, 4, 5, 6, 7, 8}; + wrapper rx(x); + auto v = rx | views::chunk(3); + auto i = ranges::begin(v); + VERIFY( ranges::equal(*i, (int[]){1, 2, 3}) ); + ++i; + VERIFY( ranges::equal(*i, (int[]){4, 5, 6}) ); + ++i; + VERIFY( ranges::equal(*i, (int[]){7, 8}) ); + i++; + VERIFY( i == ranges::end(v) ); + + for (int i = 1; i <= 10; ++i) + VERIFY( ranges::equal(wrapper(x) | views::chunk(i) | views::join, x) ); +} + +int +main() +{ + static_assert(test01()); + test02<__gnu_test::test_input_range>(); + test02<__gnu_test::test_forward_range>(); +} From patchwork Mon Sep 12 16:45:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1169 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5044:0:0:0:0:0 with SMTP id h4csp1964575wrt; Mon, 12 Sep 2022 09:49:11 -0700 (PDT) X-Google-Smtp-Source: AA6agR4e8Dwvl16yz0vP9c9xmSMvOVpgByuAa2Zsgx2mv0DssC8jkOYjT4FRGWIbHs9v6itJ75Oa X-Received: by 2002:a05:6402:f92:b0:44e:84e0:1d2a with SMTP id eh18-20020a0564020f9200b0044e84e01d2amr22715194edb.395.1663001351382; Mon, 12 Sep 2022 09:49:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663001351; cv=none; d=google.com; s=arc-20160816; b=dYFM00iA91CqCFCsqO5C+4F3k6REM03WoVjUGD8Ux6ZjJ8KBhT/WFab7FOH7+vkBL6 pwGlOwd0FWYQNsDcijmlFWSnDjklP8wqPe5dvy1sKuGQnOOtLgcXdmSES/8fJga9FZYM oXhB81RKlAWVKOLaS/W6LdMkc7y7HCxUFPfY469iNWkx/F1WKDXzCZTwEaHClrVTulmN FLKDWwGB+yf72sWxjc3fXSEJP/iwYQGs0BOxVpYJupNUtkK+fR/J/J1knjuBpS6JHd+A OppsYcETPVErCSqOPEn2e6RPWmmA406ta8bJFtsZF4M/n/MN7XvCQfqXRfSZ4lqNsQGG mprQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=L+EwGAsQOiPwZ1pW6C+ftRBmzrK06rWUBgz2uYYZ23g=; b=AV+J8QePSrE/4DVNSSOg6XUOLSzklZol9vUDQqP+qImCrt8W0DP6rDYGW+2pX4Vc74 NA4VGj5daCUIg+xJHUeyOL0P7nj9agz8WlI79Y7LiPQOFsC5STBoJrBrcjcXRbLTYet6 rKzL1tJjdTxNDEZAKj2wRL9l5zlJySHL9ZoxNeAQNpL8JF/oN/t0WRPeJurJvJWuWmft wGPu0LagFfhgUpC8k2xmZ9OyRzaGkaMmzfHvlXwp/vWRhO1e1s+fBnaca2Py/eMWaGE2 s/IlhOl8Sz+2k59dZ8+B8I+NPmfqKoGh82Mi2SeRzI/uRBjYNFgcvysuLIqX+/WYdUyi TWlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=i3TcmSoz; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id b11-20020a056402278b00b00451fabfd89csi1671534ede.552.2022.09.12.09.49.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:49:11 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=i3TcmSoz; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EC72B3948A6A for ; Mon, 12 Sep 2022 16:47:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EC72B3948A6A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663001256; bh=L+EwGAsQOiPwZ1pW6C+ftRBmzrK06rWUBgz2uYYZ23g=; 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=i3TcmSozl3HbSyfHF6a/0HtQCwGpByj+CEiJhPaPsu2IkyYbiqU7qRG8zbutQGpwR rGbX2WuSfty6QvAvhl4HGAwibJ11qpgOIxwf7u/Ba/B4S0ksnyv1I65yUkcELTg21d aGHR82HLSDSggeruQLXGyVt9/uot82Q2oL9f++Wg= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 1A08F38A90AE for ; Mon, 12 Sep 2022 16:45:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1A08F38A90AE Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-452-q752GvOaPoeC3aTVR_Mf1A-1; Mon, 12 Sep 2022 12:45:44 -0400 X-MC-Unique: q752GvOaPoeC3aTVR_Mf1A-1 Received: by mail-qk1-f200.google.com with SMTP id bl17-20020a05620a1a9100b006cdf19243acso5506617qkb.4 for ; Mon, 12 Sep 2022 09:45:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=L+EwGAsQOiPwZ1pW6C+ftRBmzrK06rWUBgz2uYYZ23g=; b=k4UJ64QZUw+GXmr5wnPauyC1oEQbrYnbU3eYir9dnMi8aEGM9vRJMxDP11TbEh/ImU GKpZe84xXbokA3JhRyvQNMODNMyL6fqgzxYDP50qflG0caxAWKE2h+QiYn7J89yJrmn0 FLlcuXVbDaz5r7nzEwGvh1im7HehAgZuvqNlYm3Rg6DCcDrfmSjUP++1rZ16Zw1Jf9S4 gN6fGel1nOTZWljx7zcFGzsRb1grPahMgTsHGII898mvZXrg+hXQmruRsDpjWOrnXKOC HgrdG0wUvYZYojBMNGDo2euBydxg8vWe3gksFysbUrgZ5xC59UNp6iCr2OtENbGkykEV WYmA== X-Gm-Message-State: ACgBeo2Q7/ruO4bPX2a8xpWHT8euKlrQo5MnnBRoZOOSHSSZadNB8Rud Exp+K1zMix6EEGRFFnFDEsxqqW8tZFK3JzYI1xlUR2WWbISWb5+KEeXPETKxNiJIlXsxtoojRp7 AspvOAkkBZFsPhfEc6ASDXYh378ZaBvoQVMNZqUSjsrv/jBjdAfykK1d7i3t6RcfOtSw= X-Received: by 2002:a37:395:0:b0:6cd:cca6:4b8a with SMTP id 143-20020a370395000000b006cdcca64b8amr10704733qkd.573.1663001144080; Mon, 12 Sep 2022 09:45:44 -0700 (PDT) X-Received: by 2002:a37:395:0:b0:6cd:cca6:4b8a with SMTP id 143-20020a370395000000b006cdcca64b8amr10704709qkd.573.1663001143650; Mon, 12 Sep 2022 09:45:43 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id 17-20020ac85651000000b0035ba48c032asm6667350qtt.25.2022.09.12.09.45.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 09:45:43 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 4/4] libstdc++: Implement ranges::slide_view from P2442R1 Date: Mon, 12 Sep 2022 12:45:31 -0400 Message-Id: <20220912164531.1742034-4-ppalka@redhat.com> X-Mailer: git-send-email 2.37.3.542.gdd3f6c4cae In-Reply-To: <20220912164531.1742034-1-ppalka@redhat.com> References: <20220912164531.1742034-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=unavailable 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.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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1743783305313212477?= X-GMAIL-MSGID: =?utf-8?q?1743783305313212477?= This also implements the LWG 3711 and 3712 changes to slide_view. libstdc++-v3/ChangeLog: * include/std/ranges (__detail::__slide_caches_nothing): Define. (__detail::__slide_caches_last): Define. (__detail::__slide_caches_first): Define. (slide_view): Define. (enable_borrowed_range): Define. (slide_view::_Iterator): Define. (slide_view::_Sentinel): Define. (views::__detail::__can_slide_view): Define. (views::_Slide, views::slide): Define. * testsuite/std/ranges/adaptors/slide/1.cc: New test. --- libstdc++-v3/include/std/ranges | 364 ++++++++++++++++++ .../testsuite/std/ranges/adaptors/slide/1.cc | 105 +++++ 2 files changed, 469 insertions(+) create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 7533b60c1d6..bbe4fa278d2 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -6314,6 +6314,370 @@ namespace views::__adaptor inline constexpr _Chunk chunk; } + namespace __detail + { + template + concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>; + + template + concept __slide_caches_last + = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>; + + template + concept __slide_caches_first + = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>; + } + + template + requires view<_Vp> + class slide_view : public view_interface> + { + _Vp _M_base; + range_difference_t<_Vp> _M_n; + [[no_unique_address]] + __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>, + __detail::_CachedPosition<_Vp>> _M_cached_begin; + [[no_unique_address]] + __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>, + __detail::_CachedPosition<_Vp>> _M_cached_end; + + template class _Iterator; + class _Sentinel; + + public: + constexpr explicit + slide_view(_Vp __base, range_difference_t<_Vp> __n) + : _M_base(std::move(__base)), _M_n(__n) + { __glibcxx_assert(__n > 0); } + + constexpr auto + begin() requires (!(__detail::__simple_view<_Vp> + && __detail::__slide_caches_nothing)) + { + if constexpr (__detail::__slide_caches_first<_Vp>) + { + iterator_t<_Vp> __it; + if (_M_cached_begin._M_has_value()) + __it = _M_cached_begin._M_get(_M_base); + else + { + __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base)); + _M_cached_begin._M_set(_M_base, __it); + } + return _Iterator(ranges::begin(_M_base), std::move(__it), _M_n); + } + else + return _Iterator(ranges::begin(_M_base), _M_n); + } + + constexpr auto + begin() const requires __detail::__slide_caches_nothing + { return _Iterator(ranges::begin(_M_base), _M_n); } + + constexpr auto + end() requires (!(__detail::__simple_view<_Vp> + && __detail::__slide_caches_nothing)) + { + if constexpr (__detail::__slide_caches_nothing<_Vp>) + return _Iterator(ranges::begin(_M_base) + range_difference_t<_Vp>(size()), + _M_n); + else if constexpr (__detail::__slide_caches_last<_Vp>) + { + iterator_t<_Vp> __it; + if (_M_cached_end._M_has_value()) + __it = _M_cached_end._M_get(_M_base); + else + { + __it = ranges::prev(ranges::end(_M_base), _M_n - 1, + ranges::begin(_M_base)); + _M_cached_end._M_set(_M_base, __it); + } + return _Iterator(std::move(__it), _M_n); + } + else if constexpr (common_range<_Vp>) + return _Iterator(ranges::end(_M_base), ranges::end(_M_base), _M_n); + else + return _Sentinel(ranges::end(_M_base)); + } + + constexpr auto + end() const requires __detail::__slide_caches_nothing + { return begin() + range_difference_t(size()); } + + constexpr auto + size() requires sized_range<_Vp> + { + auto __sz = ranges::distance(_M_base) - _M_n + 1; + if (__sz < 0) + __sz = 0; + return __detail::__to_unsigned_like(__sz); + } + + constexpr auto + size() const requires sized_range + { + auto __sz = ranges::distance(_M_base) - _M_n + 1; + if (__sz < 0) + __sz = 0; + return __detail::__to_unsigned_like(__sz); + } + }; + + template + slide_view(_Range&&, range_difference_t<_Range>) -> slide_view>; + + template + inline constexpr bool enable_borrowed_range> + = enable_borrowed_range<_Vp>; + + template + requires view<_Vp> + template + class slide_view<_Vp>::_Iterator + { + using _Base = __detail::__maybe_const_t<_Const, _Vp>; + static constexpr bool _S_last_elt_present + = __detail::__slide_caches_first<_Base>; + + iterator_t<_Base> _M_current = iterator_t<_Base>(); + [[no_unique_address]] + __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>> + _M_last_elt = decltype(_M_last_elt)(); + range_difference_t<_Base> _M_n = 0; + + constexpr + _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n) + requires (!_S_last_elt_present) + : _M_current(__current), _M_n(__n) + { } + + constexpr + _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt, + range_difference_t<_Base> __n) + requires _S_last_elt_present + : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n) + { } + + static auto + _S_iter_concept() + { + if constexpr (random_access_range<_Base>) + return random_access_iterator_tag{}; + else if constexpr (bidirectional_range<_Base>) + return bidirectional_iterator_tag{}; + else + return forward_iterator_tag{}; + } + + friend slide_view; + friend slide_view::_Sentinel; + + public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(_S_iter_concept()); + using value_type = decltype(views::counted(_M_current, _M_n)); + using difference_type = range_difference_t<_Base>; + + _Iterator() = default; + + constexpr + _Iterator(_Iterator __i) + requires _Const && convertible_to, iterator_t<_Base>> + : _M_current(std::move(__i._M_current)), _M_n(__i._M_n) + { } + + constexpr auto + operator*() const + { return views::counted(_M_current, _M_n); } + + constexpr _Iterator& + operator++() + { + ++_M_current; + if constexpr (_S_last_elt_present) + ++_M_last_elt; + return *this; + } + + constexpr _Iterator + operator++(int) + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr _Iterator& + operator--() requires bidirectional_range<_Base> + { + --_M_current; + if constexpr (_S_last_elt_present) + --_M_last_elt; + return *this; + } + + constexpr _Iterator + operator--(int) requires bidirectional_range<_Base> + { + auto __tmp = *this; + --*this; + return __tmp; + } + + constexpr _Iterator& + operator+=(difference_type __x) + requires random_access_range<_Base> + { + _M_current += __x; + if constexpr (_S_last_elt_present) + _M_last_elt += __x; + return *this; + } + + constexpr _Iterator& + operator-=(difference_type __x) + requires random_access_range<_Base> + { + _M_current -= __x; + if constexpr (_S_last_elt_present) + _M_last_elt -= __x; + return *this; + } + + constexpr auto + operator[](difference_type __n) const + requires random_access_range<_Base> + { return views::counted(_M_current + __n, _M_n); } + + friend constexpr bool + operator==(const _Iterator& __x, const _Iterator& __y) + { + if constexpr (_S_last_elt_present) + return __x._M_last_elt == __y._M_last_elt; + else + return __x._M_current == __y._M_current; + } + + friend constexpr bool + operator<(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return __x._M_current < __y._M_current; } + + friend constexpr bool + operator>(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return __y < __x; } + + friend constexpr bool + operator<=(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return !(__y < __x); } + + friend constexpr bool + operator>=(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return !(__x < __y); } + + friend constexpr auto + operator<=>(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + && three_way_comparable> + { return __x._M_current <=> __y._M_current; } + + friend constexpr _Iterator + operator+(const _Iterator& __i, difference_type __n) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __n; + return __r; + } + + friend constexpr _Iterator + operator+(difference_type __n, const _Iterator& __i) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __n; + return __r; + } + + friend constexpr _Iterator + operator-(const _Iterator& __i, difference_type __n) + requires random_access_range<_Base> + { + auto __r = __i; + __r -= __n; + return __r; + } + + friend constexpr difference_type + operator-(const _Iterator& __x, const _Iterator& __y) + requires sized_sentinel_for, iterator_t<_Base>> + { + if constexpr (_S_last_elt_present) + return __x._M_last_elt - __y._M_last_elt; + else + return __x._M_current - __y._M_current; + } + }; + + template + requires view<_Vp> + class slide_view<_Vp>::_Sentinel + { + sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); + + constexpr explicit + _Sentinel(sentinel_t<_Vp> __end) + : _M_end(__end) + { } + + friend slide_view; + + public: + _Sentinel() = default; + + friend constexpr bool + operator==(const _Iterator& __x, const _Sentinel& __y) + { return __x._M_last_elt == __y._M_end; } + + friend constexpr range_difference_t<_Vp> + operator-(const _Iterator& __x, const _Sentinel& __y) + requires sized_sentinel_for, iterator_t<_Vp>> + { return __x._M_last_elt - __y._M_end; } + + friend constexpr range_difference_t<_Vp> + operator-(const _Sentinel& __y, const _Iterator& __x) + requires sized_sentinel_for, iterator_t<_Vp>> + { return __y._M_end -__x._M_last_elt; } + }; + + namespace views + { + namespace __detail + { + template + concept __can_slide_view + = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); }; + } + + struct _Slide : __adaptor::_RangeAdaptor<_Slide> + { + template> + requires __detail::__can_slide_view<_Range, _Dp> + constexpr auto + operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const + { return slide_view(std::forward<_Range>(__r), __n); } + + using __adaptor::_RangeAdaptor<_Slide>::operator(); + static constexpr int _S_arity = 2; + static constexpr bool _S_has_simple_extra_args = true; + }; + + inline constexpr _Slide slide; + } + #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc new file mode 100644 index 00000000000..98560420810 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc @@ -0,0 +1,105 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include +#include +#include + +namespace ranges = std::ranges; +namespace views = std::views; + +constexpr bool +test01() +{ + auto v1 = std::array{1, 2} | views::slide(1); + const auto i0 = v1.begin(), i1 = v1.begin() + 1; + VERIFY( i0 + 1 - 1 == i0 ); + VERIFY( i0 < i1 ); + VERIFY( i1 < v1.end() ); + VERIFY( i1 - i0 == 1 ); + VERIFY( i0 - i1 == -1 ); + VERIFY( v1.end() - i1 == 1 ); + VERIFY( i1 - v1.end() == -1 ); + VERIFY( ranges::equal(std::move(v1) | views::join, (int[]){1, 2}) ); + + int x[] = {1, 2, 3, 4}; + auto v2 = x | views::slide(2); + auto i2 = v2.begin(); + i2 += 2; + i2 -= -1; + VERIFY( i2 == v2.end() ); + VERIFY( ranges::size(v2) == 3 ); + VERIFY( ranges::size(std::as_const(v2)) == 3 ); + VERIFY( ranges::equal(v2, (std::initializer_list[]){{1, 2}, {2, 3}, {3, 4}}, + ranges::equal) ); + + int y[] = {1, 2, 3, 4, 5}; + const auto v3 = y | views::slide(3); + VERIFY( ranges::size(v3) == 3 ); + for (unsigned i = 0; i < ranges::size(x); i++) + { + VERIFY( &v3[i][0] == &y[i] + 0 ); + VERIFY( &v3[i][1] == &y[i] + 1 ); + VERIFY( &v3[i][2] == &y[i] + 2 ); + } + + const auto v5 = y | views::slide(5); + VERIFY( ranges::size(v5) == 1 ); + VERIFY( ranges::equal(v5 | views::join, y) ); + + const auto v6 = y | views::slide(6); + VERIFY( ranges::empty(v6) ); + + return true; +} + +constexpr bool +test02() +{ + using __gnu_test::test_input_range; + using __gnu_test::test_forward_range; + using __gnu_test::test_random_access_range; + + using ty1 = ranges::slide_view>>; + static_assert(ranges::forward_range); + static_assert(!ranges::bidirectional_range); + static_assert(!ranges::sized_range); + + using ty2 = ranges::slide_view>>; + static_assert(ranges::random_access_range); + static_assert(ranges::sized_range); + + return true; +} + +constexpr bool +test03() +{ + auto v = views::iota(0, 4) | views::filter([](auto) { return true; }) | views::slide(2); + using ty = decltype(v); + static_assert(ranges::forward_range); + static_assert(ranges::common_range); + static_assert(!ranges::sized_range); + VERIFY( v.begin() == v.begin() ); + VERIFY( v.begin() != v.end() ); + VERIFY( ranges::next(v.begin(), 3) == v.end() ); + auto it = v.begin(); + ++it; + it++; + VERIFY( ranges::next(it) == v.end() ); + it--; + --it; + VERIFY( it == v.begin() ); + + return true; +} + +int +main() +{ + static_assert(test01()); + static_assert(test02()); + static_assert(test03()); +}