From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 777093857820 for ; Fri, 15 Oct 2021 17:30:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 777093857820 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-530-jKKMfnchMZKVc3TDrPz8Cw-1; Fri, 15 Oct 2021 13:30:10 -0400 X-MC-Unique: jKKMfnchMZKVc3TDrPz8Cw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D2305802575; Fri, 15 Oct 2021 17:30:09 +0000 (UTC) Received: from localhost (unknown [10.33.36.131]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7BB7B19736; Fri, 15 Oct 2021 17:30:09 +0000 (UTC) Date: Fri, 15 Oct 2021 18:30:08 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Make non-propagating-cache fully constexpr [PR101263] Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="RnFRdIj/iHkUGGeh" Content-Disposition: inline X-Spam-Status: No, score=-13.8 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_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Oct 2021 17:30:15 -0000 --RnFRdIj/iHkUGGeh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline libstdc++-v3/ChangeLog: PR libstdc++/101263 * include/std/ranges (__cached): New wrapper struct. (__non_propagating_cache): Use __cached for contained value. (__non_propagating_cache::_M_emplace_deref): Add constexpr. Use std::construct_at instead of placement new. * testsuite/std/ranges/adaptors/join.cc: Check constexpr works. Tested powerpc64le-linux. Committed to trunk. --RnFRdIj/iHkUGGeh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 2c564e813c0626802e5bfb066c094933d5e6a774 Author: Jonathan Wakely Date: Fri Oct 15 14:49:21 2021 libstdc++: Make non-propagating-cache fully constexpr [PR101263] libstdc++-v3/ChangeLog: PR libstdc++/101263 * include/std/ranges (__cached): New wrapper struct. (__non_propagating_cache): Use __cached for contained value. (__non_propagating_cache::_M_emplace_deref): Add constexpr. Use std::construct_at instead of placement new. * testsuite/std/ranges/adaptors/join.cc: Check constexpr works. diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 07eae0cf94b..b8de400dfbb 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1159,9 +1159,34 @@ namespace views::__adaptor // (such as join_view::_M_inner). }; + template + struct __cached + { + struct _Deref_t { }; + static constexpr _Deref_t __deref{}; + + // Initialize _M_t directly from the result of dereferencing __i. + // This avoids any unwanted temporary materialization that would + // occur if *__i was bound to a reference before initializing _M_t. + template + constexpr explicit + __cached(_Deref_t, _Iter&& __i) + : _M_t(*__i) + { } + + template + constexpr explicit + __cached(_Args&&... __args) + : _M_t(std::forward<_Args>(__args)...) + { } + + _Tp _M_t; + }; + template requires is_object_v<_Tp> - struct __non_propagating_cache<_Tp> : protected _Optional_base<_Tp> + struct __non_propagating_cache<_Tp> + : protected _Optional_base<__cached<_Tp>> { __non_propagating_cache() = default; @@ -1205,23 +1230,22 @@ namespace views::__adaptor constexpr _Tp& operator*() noexcept - { return this->_M_get(); } + { return this->_M_get()._M_t; } constexpr const _Tp& operator*() const noexcept - { return this->_M_get(); } + { return this->_M_get()._M_t; } template - _Tp& + constexpr _Tp& _M_emplace_deref(const _Iter& __i) { this->_M_reset(); - // Using _Optional_base::_M_construct to initialize from '*__i' - // would incur an extra move due to the indirection, so we instead - // use placement new directly. - ::new ((void *) std::__addressof(this->_M_payload._M_payload)) _Tp(*__i); + // Use the special constructor of __cached<_Tp> that does *__i. + std::construct_at(std::__addressof(this->_M_payload._M_payload), + std::in_place, __cached<_Tp>::__deref, __i); this->_M_payload._M_engaged = true; - return this->_M_get(); + return **this; } }; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc index 50af3fdf729..1ec42381ad2 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc @@ -193,6 +193,18 @@ test11() ; } +void +test12() +{ + // PR libstdc++/101263 + constexpr auto b = [] { + auto r = std::views::iota(0, 5) + | std::views::lazy_split(0) + | std::views::join; + return r.begin() != r.end(); + }(); +} + int main() { @@ -207,4 +219,5 @@ main() test09(); test10(); test11(); + test12(); } --RnFRdIj/iHkUGGeh--