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 B4F853857C70 for ; Sat, 28 Aug 2021 12:14:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B4F853857C70 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-142-fLF5iiMSPGWn8nUMbyFD5A-1; Sat, 28 Aug 2021 08:14:57 -0400 X-MC-Unique: fLF5iiMSPGWn8nUMbyFD5A-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 87C6C801B3C; Sat, 28 Aug 2021 12:14:56 +0000 (UTC) Received: from localhost (unknown [10.33.36.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id F00105D9FC; Sat, 28 Aug 2021 12:14:55 +0000 (UTC) Date: Sat, 28 Aug 2021 13:14:54 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [committed] libstdc++: Avoid a move in std::function construction (LWG 2447) Message-ID: References: MIME-Version: 1.0 In-Reply-To: X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="2YdF26zD8aQqrpCG" Content-Disposition: inline X-Spam-Status: No, score=-15.1 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: Sat, 28 Aug 2021 12:15:01 -0000 --2YdF26zD8aQqrpCG Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline On 27/08/21 00:13 +0100, Jonathan Wakely wrote: >This makes the std::function constructor use perfect forwarding, to >avoid an unnecessary move-construction of the target. This means we need >to rewrite the _Function_base::_Base_manager::_M_init_functor function >to use a forwarding reference, and so can reuse it for the clone >operation. > >Also simplify the SFINAE constraints on the constructor, by combining >the !is_same_v, function> constraint into the >_Callable trait. > >Signed-off-by: Jonathan Wakely > >libstdc++-v3/ChangeLog: > > * include/bits/std_function.h (_function_base::_Base_manager): > Replace _M_init_functor with a function template using a > forwarding reference, and a pair of _M_create function > templates. Reuse _M_create for the clone operation. > (function::_Decay_t): New alias template. > (function::_Callable): Simplify by using _Decay. > (function::function(F)): Change parameter to forwarding > reference, as per LWG 2447. Add noexcept-specifier. Simplify > constraints. > (function::operator=(F&&)): Add noexcept-specifier. > * testsuite/20_util/function/cons/lwg2774.cc: New test. > * testsuite/20_util/function/cons/noexcept.cc: New test. > This makes the new static_asserts give a slightly nicer error message that doesn't involve . Tested powerpc64le-linux. Committed to trunk. --2YdF26zD8aQqrpCG Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 952095bb053cfef47b48cc4345d658b8d8829800 Author: Jonathan Wakely Date: Fri Aug 27 00:20:31 2021 libstdc++: Name std::function template parameter This avoids "" being shown in the diagnostics for ill-formed uses of std::function constructor: In instantiation of 'std::function<_Res(_ArgTypes ...)>::function(_Functor&&) [with _Functor = f(f()::_Z1fv.frame*)::; = void; _Res = void; _ArgTypes = {}]' Instead we get: In instantiation of 'std::function<_Res(_ArgTypes ...)>::function(_Functor&&) [with _Functor = f(f()::_Z1fv.frame*)::; _Constraints = void; _Res = void; _ArgTypes = {}]' Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/bits/std_function.h (function::function(F&&)): Give name to defaulted template parameter, to improve diagnostics. Use markdown for more doxygen comments. diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h index 82c932e0db5..3dda820bd1a 100644 --- a/libstdc++-v3/include/bits/std_function.h +++ b/libstdc++-v3/include/bits/std_function.h @@ -326,10 +326,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; /** - * @brief Primary class template for std::function. + * @brief Polymorphic function wrapper. * @ingroup functors - * - * Polymorphic function wrapper. + * @since C++11 */ template class function<_Res(_ArgTypes...)> @@ -364,7 +363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Default construct creates an empty function call wrapper. - * @post @c !(bool)*this + * @post `!(bool)*this` */ function() noexcept : _Function_base() { } @@ -379,10 +378,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief %Function copy constructor. * @param __x A %function object with identical call signature. - * @post @c bool(*this) == bool(__x) + * @post `bool(*this) == bool(__x)` * - * The newly-created %function contains a copy of the target of @a - * __x (if it has one). + * The newly-created %function contains a copy of the target of + * `__x` (if it has one). */ function(const function& __x) : _Function_base() @@ -399,7 +398,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief %Function move constructor. * @param __x A %function object rvalue with identical call signature. * - * The newly-created %function contains the target of @a __x + * The newly-created %function contains the target of `__x` * (if it has one). */ function(function&& __x) noexcept @@ -418,22 +417,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief Builds a %function that targets a copy of the incoming * function object. * @param __f A %function object that is callable with parameters of - * type @c T1, @c T2, ..., @c TN and returns a value convertible - * to @c Res. + * type `ArgTypes...` and returns a value convertible to `Res`. * * The newly-created %function object will target a copy of - * @a __f. If @a __f is @c reference_wrapper, then this function - * object will contain a reference to the function object @c - * __f.get(). If @a __f is a NULL function pointer or NULL - * pointer-to-member, the newly-created object will be empty. + * `__f`. If `__f` is `reference_wrapper`, then this function + * object will contain a reference to the function object `__f.get()`. + * If `__f` is a null function pointer, null pointer-to-member, or + * empty `std::function`, the newly-created object will be empty. * - * If @a __f is a non-NULL function pointer or an object of type @c - * reference_wrapper, this function will not throw. + * If `__f` is a non-null function pointer or an object of type + * `reference_wrapper`, this function will not throw. */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2774. std::function construction vs assignment template>> + typename _Constraints = _Requires<_Callable<_Functor>>> function(_Functor&& __f) noexcept(_Handler<_Functor>::template _S_nothrow_init<_Functor>()) : _Function_base() --2YdF26zD8aQqrpCG--