Files
gcc/libstdc++-v3/include/bits/funcwrap.h

632 lines
18 KiB
C
Raw Normal View History

libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
// Implementation of std::move_only_function, std::copyable_function
// and std::function_ref -*- C++ -*-
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/funcwrap.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _GLIBCXX_FUNCWRAP_H
#define _GLIBCXX_FUNCWRAP_H 1
libstdc++: #ifdef out #pragma GCC system_header In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build flags to help catch problems in the library. This patch takes a different approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is defined. As a result, the testsuites will treat them as non-system-headers to get better warning coverage during regression testing of both gcc and libstdc++, not just when building the library. My rationale for the #ifdef instead of just removing the #pragma is the three G++ tests that want to test libstdc++ system header behavior, so we need a way to select it. This doesn't affect installed libraries, as they get their system-header status from the lookup path. But testsuite_flags --build-includes gives -I directives rather than -isystem. This patch doesn't change the headers in config/ because I'm not compiling with most of them, so won't see any warnings that need fixing. Adjusting them could happen later, or we can not bother. libstdc++-v3/ChangeLog: * acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers. * configure: Regenerate. * include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header. * include/bits/atomic_base.h * include/bits/atomic_futex.h * include/bits/atomic_timed_wait.h * include/bits/atomic_wait.h * include/bits/basic_ios.h * include/bits/basic_string.h * include/bits/boost_concept_check.h * include/bits/char_traits.h * include/bits/charconv.h * include/bits/chrono.h * include/bits/chrono_io.h * include/bits/codecvt.h * include/bits/concept_check.h * include/bits/cpp_type_traits.h * include/bits/elements_of.h * include/bits/enable_special_members.h * include/bits/erase_if.h * include/bits/forward_list.h * include/bits/functional_hash.h * include/bits/gslice.h * include/bits/gslice_array.h * include/bits/hashtable.h * include/bits/indirect_array.h * include/bits/invoke.h * include/bits/ios_base.h * include/bits/iterator_concepts.h * include/bits/locale_classes.h * include/bits/locale_facets.h * include/bits/locale_facets_nonio.h * include/bits/localefwd.h * include/bits/mask_array.h * include/bits/max_size_type.h * include/bits/memory_resource.h * include/bits/memoryfwd.h * include/bits/move_only_function.h * include/bits/node_handle.h * include/bits/ostream_insert.h * include/bits/out_ptr.h * include/bits/parse_numbers.h * include/bits/postypes.h * include/bits/quoted_string.h * include/bits/range_access.h * include/bits/ranges_base.h * include/bits/refwrap.h * include/bits/sat_arith.h * include/bits/semaphore_base.h * include/bits/slice_array.h * include/bits/std_abs.h * include/bits/std_function.h * include/bits/std_mutex.h * include/bits/std_thread.h * include/bits/stl_iterator_base_funcs.h * include/bits/stl_iterator_base_types.h * include/bits/stl_tree.h * include/bits/stream_iterator.h * include/bits/streambuf_iterator.h * include/bits/stringfwd.h * include/bits/this_thread_sleep.h * include/bits/unique_lock.h * include/bits/uses_allocator_args.h * include/bits/utility.h * include/bits/valarray_after.h * include/bits/valarray_array.h * include/bits/valarray_before.h * include/bits/version.h * include/c_compatibility/fenv.h * include/c_compatibility/inttypes.h * include/c_compatibility/stdint.h * include/decimal/decimal.h * include/experimental/bits/net.h * include/experimental/bits/shared_ptr.h * include/ext/aligned_buffer.h * include/ext/alloc_traits.h * include/ext/atomicity.h * include/ext/concurrence.h * include/ext/numeric_traits.h * include/ext/pod_char_traits.h * include/ext/pointer.h * include/ext/stdio_filebuf.h * include/ext/stdio_sync_filebuf.h * include/ext/string_conversions.h * include/ext/type_traits.h * include/ext/vstring.h * include/ext/vstring_fwd.h * include/ext/vstring_util.h * include/parallel/algorithmfwd.h * include/parallel/numericfwd.h * include/tr1/functional_hash.h * include/tr1/hashtable.h * include/tr1/random.h * libsupc++/exception.h * libsupc++/hash_bytes.h * include/bits/basic_ios.tcc * include/bits/basic_string.tcc * include/bits/fstream.tcc * include/bits/istream.tcc * include/bits/locale_classes.tcc * include/bits/locale_facets.tcc * include/bits/locale_facets_nonio.tcc * include/bits/ostream.tcc * include/bits/sstream.tcc * include/bits/streambuf.tcc * include/bits/string_view.tcc * include/bits/version.tpl * include/experimental/bits/string_view.tcc * include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp * include/ext/random.tcc * include/ext/vstring.tcc * include/tr2/bool_set.tcc * include/tr2/dynamic_bitset.tcc * include/bits/c++config * include/c/cassert * include/c/cctype * include/c/cerrno * include/c/cfloat * include/c/ciso646 * include/c/climits * include/c/clocale * include/c/cmath * include/c/csetjmp * include/c/csignal * include/c/cstdarg * include/c/cstddef * include/c/cstdio * include/c/cstdlib * include/c/cstring * include/c/ctime * include/c/cuchar * include/c/cwchar * include/c/cwctype * include/c_global/cassert * include/c_global/ccomplex * include/c_global/cctype * include/c_global/cerrno * include/c_global/cfenv * include/c_global/cfloat * include/c_global/cinttypes * include/c_global/ciso646 * include/c_global/climits * include/c_global/clocale * include/c_global/cmath * include/c_global/csetjmp * include/c_global/csignal * include/c_global/cstdalign * include/c_global/cstdarg * include/c_global/cstdbool * include/c_global/cstddef * include/c_global/cstdint * include/c_global/cstdio * include/c_global/cstdlib * include/c_global/cstring * include/c_global/ctgmath * include/c_global/ctime * include/c_global/cuchar * include/c_global/cwchar * include/c_global/cwctype * include/c_std/cassert * include/c_std/cctype * include/c_std/cerrno * include/c_std/cfloat * include/c_std/ciso646 * include/c_std/climits * include/c_std/clocale * include/c_std/cmath * include/c_std/csetjmp * include/c_std/csignal * include/c_std/cstdarg * include/c_std/cstddef * include/c_std/cstdio * include/c_std/cstdlib * include/c_std/cstring * include/c_std/ctime * include/c_std/cuchar * include/c_std/cwchar * include/c_std/cwctype * include/debug/array * include/debug/bitset * include/debug/deque * include/debug/forward_list * include/debug/list * include/debug/map * include/debug/set * include/debug/string * include/debug/unordered_map * include/debug/unordered_set * include/debug/vector * include/decimal/decimal * include/experimental/algorithm * include/experimental/any * include/experimental/array * include/experimental/buffer * include/experimental/chrono * include/experimental/contract * include/experimental/deque * include/experimental/executor * include/experimental/filesystem * include/experimental/forward_list * include/experimental/functional * include/experimental/internet * include/experimental/io_context * include/experimental/iterator * include/experimental/list * include/experimental/map * include/experimental/memory * include/experimental/memory_resource * include/experimental/net * include/experimental/netfwd * include/experimental/numeric * include/experimental/propagate_const * include/experimental/ratio * include/experimental/regex * include/experimental/scope * include/experimental/set * include/experimental/socket * include/experimental/string * include/experimental/string_view * include/experimental/synchronized_value * include/experimental/system_error * include/experimental/timer * include/experimental/tuple * include/experimental/type_traits * include/experimental/unordered_map * include/experimental/unordered_set * include/experimental/vector * include/ext/algorithm * include/ext/cmath * include/ext/functional * include/ext/iterator * include/ext/memory * include/ext/numeric * include/ext/random * include/ext/rb_tree * include/ext/rope * include/parallel/algorithm * include/std/algorithm * include/std/any * include/std/array * include/std/atomic * include/std/barrier * include/std/bit * include/std/bitset * include/std/charconv * include/std/chrono * include/std/codecvt * include/std/complex * include/std/concepts * include/std/condition_variable * include/std/coroutine * include/std/deque * include/std/execution * include/std/expected * include/std/filesystem * include/std/format * include/std/forward_list * include/std/fstream * include/std/functional * include/std/future * include/std/generator * include/std/iomanip * include/std/ios * include/std/iosfwd * include/std/iostream * include/std/istream * include/std/iterator * include/std/latch * include/std/limits * include/std/list * include/std/locale * include/std/map * include/std/memory * include/std/memory_resource * include/std/mutex * include/std/numbers * include/std/numeric * include/std/optional * include/std/ostream * include/std/print * include/std/queue * include/std/random * include/std/ranges * include/std/ratio * include/std/regex * include/std/scoped_allocator * include/std/semaphore * include/std/set * include/std/shared_mutex * include/std/span * include/std/spanstream * include/std/sstream * include/std/stack * include/std/stacktrace * include/std/stdexcept * include/std/streambuf * include/std/string * include/std/string_view * include/std/syncstream * include/std/system_error * include/std/text_encoding * include/std/thread * include/std/tuple * include/std/type_traits * include/std/typeindex * include/std/unordered_map * include/std/unordered_set * include/std/utility * include/std/valarray * include/std/variant * include/std/vector * include/std/version * include/tr1/array * include/tr1/cfenv * include/tr1/cinttypes * include/tr1/cmath * include/tr1/complex * include/tr1/cstdbool * include/tr1/cstdint * include/tr1/cstdio * include/tr1/cstdlib * include/tr1/cwchar * include/tr1/cwctype * include/tr1/functional * include/tr1/memory * include/tr1/random * include/tr1/regex * include/tr1/tuple * include/tr1/type_traits * include/tr1/unordered_map * include/tr1/unordered_set * include/tr1/utility * include/tr2/bool_set * include/tr2/dynamic_bitset * include/tr2/type_traits * libsupc++/atomic_lockfree_defines.h * libsupc++/compare * libsupc++/cxxabi.h * libsupc++/cxxabi_forced.h * libsupc++/cxxabi_init_exception.h * libsupc++/exception * libsupc++/initializer_list * libsupc++/new * libsupc++/typeinfo: Likewise. * testsuite/20_util/ratio/operations/ops_overflow_neg.cc * testsuite/23_containers/array/tuple_interface/get_neg.cc * testsuite/23_containers/vector/cons/destructible_debug_neg.cc * testsuite/24_iterators/operations/prev_neg.cc * testsuite/ext/type_traits/add_unsigned_floating_neg.cc * testsuite/ext/type_traits/add_unsigned_integer_neg.cc * testsuite/ext/type_traits/remove_unsigned_floating_neg.cc * testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust line numbers. gcc/testsuite/ChangeLog * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C * g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
2024-09-12 12:15:51 -04:00
#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
libstdc++: #ifdef out #pragma GCC system_header In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build flags to help catch problems in the library. This patch takes a different approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is defined. As a result, the testsuites will treat them as non-system-headers to get better warning coverage during regression testing of both gcc and libstdc++, not just when building the library. My rationale for the #ifdef instead of just removing the #pragma is the three G++ tests that want to test libstdc++ system header behavior, so we need a way to select it. This doesn't affect installed libraries, as they get their system-header status from the lookup path. But testsuite_flags --build-includes gives -I directives rather than -isystem. This patch doesn't change the headers in config/ because I'm not compiling with most of them, so won't see any warnings that need fixing. Adjusting them could happen later, or we can not bother. libstdc++-v3/ChangeLog: * acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers. * configure: Regenerate. * include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header. * include/bits/atomic_base.h * include/bits/atomic_futex.h * include/bits/atomic_timed_wait.h * include/bits/atomic_wait.h * include/bits/basic_ios.h * include/bits/basic_string.h * include/bits/boost_concept_check.h * include/bits/char_traits.h * include/bits/charconv.h * include/bits/chrono.h * include/bits/chrono_io.h * include/bits/codecvt.h * include/bits/concept_check.h * include/bits/cpp_type_traits.h * include/bits/elements_of.h * include/bits/enable_special_members.h * include/bits/erase_if.h * include/bits/forward_list.h * include/bits/functional_hash.h * include/bits/gslice.h * include/bits/gslice_array.h * include/bits/hashtable.h * include/bits/indirect_array.h * include/bits/invoke.h * include/bits/ios_base.h * include/bits/iterator_concepts.h * include/bits/locale_classes.h * include/bits/locale_facets.h * include/bits/locale_facets_nonio.h * include/bits/localefwd.h * include/bits/mask_array.h * include/bits/max_size_type.h * include/bits/memory_resource.h * include/bits/memoryfwd.h * include/bits/move_only_function.h * include/bits/node_handle.h * include/bits/ostream_insert.h * include/bits/out_ptr.h * include/bits/parse_numbers.h * include/bits/postypes.h * include/bits/quoted_string.h * include/bits/range_access.h * include/bits/ranges_base.h * include/bits/refwrap.h * include/bits/sat_arith.h * include/bits/semaphore_base.h * include/bits/slice_array.h * include/bits/std_abs.h * include/bits/std_function.h * include/bits/std_mutex.h * include/bits/std_thread.h * include/bits/stl_iterator_base_funcs.h * include/bits/stl_iterator_base_types.h * include/bits/stl_tree.h * include/bits/stream_iterator.h * include/bits/streambuf_iterator.h * include/bits/stringfwd.h * include/bits/this_thread_sleep.h * include/bits/unique_lock.h * include/bits/uses_allocator_args.h * include/bits/utility.h * include/bits/valarray_after.h * include/bits/valarray_array.h * include/bits/valarray_before.h * include/bits/version.h * include/c_compatibility/fenv.h * include/c_compatibility/inttypes.h * include/c_compatibility/stdint.h * include/decimal/decimal.h * include/experimental/bits/net.h * include/experimental/bits/shared_ptr.h * include/ext/aligned_buffer.h * include/ext/alloc_traits.h * include/ext/atomicity.h * include/ext/concurrence.h * include/ext/numeric_traits.h * include/ext/pod_char_traits.h * include/ext/pointer.h * include/ext/stdio_filebuf.h * include/ext/stdio_sync_filebuf.h * include/ext/string_conversions.h * include/ext/type_traits.h * include/ext/vstring.h * include/ext/vstring_fwd.h * include/ext/vstring_util.h * include/parallel/algorithmfwd.h * include/parallel/numericfwd.h * include/tr1/functional_hash.h * include/tr1/hashtable.h * include/tr1/random.h * libsupc++/exception.h * libsupc++/hash_bytes.h * include/bits/basic_ios.tcc * include/bits/basic_string.tcc * include/bits/fstream.tcc * include/bits/istream.tcc * include/bits/locale_classes.tcc * include/bits/locale_facets.tcc * include/bits/locale_facets_nonio.tcc * include/bits/ostream.tcc * include/bits/sstream.tcc * include/bits/streambuf.tcc * include/bits/string_view.tcc * include/bits/version.tpl * include/experimental/bits/string_view.tcc * include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp * include/ext/random.tcc * include/ext/vstring.tcc * include/tr2/bool_set.tcc * include/tr2/dynamic_bitset.tcc * include/bits/c++config * include/c/cassert * include/c/cctype * include/c/cerrno * include/c/cfloat * include/c/ciso646 * include/c/climits * include/c/clocale * include/c/cmath * include/c/csetjmp * include/c/csignal * include/c/cstdarg * include/c/cstddef * include/c/cstdio * include/c/cstdlib * include/c/cstring * include/c/ctime * include/c/cuchar * include/c/cwchar * include/c/cwctype * include/c_global/cassert * include/c_global/ccomplex * include/c_global/cctype * include/c_global/cerrno * include/c_global/cfenv * include/c_global/cfloat * include/c_global/cinttypes * include/c_global/ciso646 * include/c_global/climits * include/c_global/clocale * include/c_global/cmath * include/c_global/csetjmp * include/c_global/csignal * include/c_global/cstdalign * include/c_global/cstdarg * include/c_global/cstdbool * include/c_global/cstddef * include/c_global/cstdint * include/c_global/cstdio * include/c_global/cstdlib * include/c_global/cstring * include/c_global/ctgmath * include/c_global/ctime * include/c_global/cuchar * include/c_global/cwchar * include/c_global/cwctype * include/c_std/cassert * include/c_std/cctype * include/c_std/cerrno * include/c_std/cfloat * include/c_std/ciso646 * include/c_std/climits * include/c_std/clocale * include/c_std/cmath * include/c_std/csetjmp * include/c_std/csignal * include/c_std/cstdarg * include/c_std/cstddef * include/c_std/cstdio * include/c_std/cstdlib * include/c_std/cstring * include/c_std/ctime * include/c_std/cuchar * include/c_std/cwchar * include/c_std/cwctype * include/debug/array * include/debug/bitset * include/debug/deque * include/debug/forward_list * include/debug/list * include/debug/map * include/debug/set * include/debug/string * include/debug/unordered_map * include/debug/unordered_set * include/debug/vector * include/decimal/decimal * include/experimental/algorithm * include/experimental/any * include/experimental/array * include/experimental/buffer * include/experimental/chrono * include/experimental/contract * include/experimental/deque * include/experimental/executor * include/experimental/filesystem * include/experimental/forward_list * include/experimental/functional * include/experimental/internet * include/experimental/io_context * include/experimental/iterator * include/experimental/list * include/experimental/map * include/experimental/memory * include/experimental/memory_resource * include/experimental/net * include/experimental/netfwd * include/experimental/numeric * include/experimental/propagate_const * include/experimental/ratio * include/experimental/regex * include/experimental/scope * include/experimental/set * include/experimental/socket * include/experimental/string * include/experimental/string_view * include/experimental/synchronized_value * include/experimental/system_error * include/experimental/timer * include/experimental/tuple * include/experimental/type_traits * include/experimental/unordered_map * include/experimental/unordered_set * include/experimental/vector * include/ext/algorithm * include/ext/cmath * include/ext/functional * include/ext/iterator * include/ext/memory * include/ext/numeric * include/ext/random * include/ext/rb_tree * include/ext/rope * include/parallel/algorithm * include/std/algorithm * include/std/any * include/std/array * include/std/atomic * include/std/barrier * include/std/bit * include/std/bitset * include/std/charconv * include/std/chrono * include/std/codecvt * include/std/complex * include/std/concepts * include/std/condition_variable * include/std/coroutine * include/std/deque * include/std/execution * include/std/expected * include/std/filesystem * include/std/format * include/std/forward_list * include/std/fstream * include/std/functional * include/std/future * include/std/generator * include/std/iomanip * include/std/ios * include/std/iosfwd * include/std/iostream * include/std/istream * include/std/iterator * include/std/latch * include/std/limits * include/std/list * include/std/locale * include/std/map * include/std/memory * include/std/memory_resource * include/std/mutex * include/std/numbers * include/std/numeric * include/std/optional * include/std/ostream * include/std/print * include/std/queue * include/std/random * include/std/ranges * include/std/ratio * include/std/regex * include/std/scoped_allocator * include/std/semaphore * include/std/set * include/std/shared_mutex * include/std/span * include/std/spanstream * include/std/sstream * include/std/stack * include/std/stacktrace * include/std/stdexcept * include/std/streambuf * include/std/string * include/std/string_view * include/std/syncstream * include/std/system_error * include/std/text_encoding * include/std/thread * include/std/tuple * include/std/type_traits * include/std/typeindex * include/std/unordered_map * include/std/unordered_set * include/std/utility * include/std/valarray * include/std/variant * include/std/vector * include/std/version * include/tr1/array * include/tr1/cfenv * include/tr1/cinttypes * include/tr1/cmath * include/tr1/complex * include/tr1/cstdbool * include/tr1/cstdint * include/tr1/cstdio * include/tr1/cstdlib * include/tr1/cwchar * include/tr1/cwctype * include/tr1/functional * include/tr1/memory * include/tr1/random * include/tr1/regex * include/tr1/tuple * include/tr1/type_traits * include/tr1/unordered_map * include/tr1/unordered_set * include/tr1/utility * include/tr2/bool_set * include/tr2/dynamic_bitset * include/tr2/type_traits * libsupc++/atomic_lockfree_defines.h * libsupc++/compare * libsupc++/cxxabi.h * libsupc++/cxxabi_forced.h * libsupc++/cxxabi_init_exception.h * libsupc++/exception * libsupc++/initializer_list * libsupc++/new * libsupc++/typeinfo: Likewise. * testsuite/20_util/ratio/operations/ops_overflow_neg.cc * testsuite/23_containers/array/tuple_interface/get_neg.cc * testsuite/23_containers/vector/cons/destructible_debug_neg.cc * testsuite/24_iterators/operations/prev_neg.cc * testsuite/ext/type_traits/add_unsigned_floating_neg.cc * testsuite/ext/type_traits/add_unsigned_integer_neg.cc * testsuite/ext/type_traits/remove_unsigned_floating_neg.cc * testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust line numbers. gcc/testsuite/ChangeLog * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C * g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
2024-09-12 12:15:51 -04:00
#endif
libstdc++: Replace all manual FTM definitions and use libstdc++-v3/ChangeLog: * libsupc++/typeinfo: Switch to bits/version.h for __cpp_lib_constexpr_typeinfo. * libsupc++/new: Switch to bits/version.h for __cpp_lib_{launder,hardware_interference_size,destroying_delete}. (launder): Guard behind __cpp_lib_launder. (hardware_destructive_interference_size) (hardware_constructive_interference_size): Guard behind __cpp_lib_hardware_interference_size. * libsupc++/exception: Switch to bits/version.h for __cpp_lib_uncaught_exceptions. (uncaught_exceptions): Guard behind __cpp_lib_uncaught_exceptions. * libsupc++/compare: Switch to bits/version.h for __cpp_lib_three_way_comparison. (three_way_comparable, three_way_comparable_with) (compare_three_way, weak_order, strong_order, partial_order): Guard behind __cpp_lib_three_way_comparison >= 201907L. * include/std/chrono: Drop __cpp_lib_chrono definition. * include/std/vector: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/variant: Switch to bits/version.h for __cpp_lib_variant. Guard whole header behind that FTM. * include/std/utility: Switch to bits/version.h for __cpp_lib_{exchange_function,constexpr_algorithms,as_const}, __cpp_lib_{integer_comparison_functions,to_underlying}, and __cpp_lib_unreachable. (exchange): Guard behind __cpp_lib_exchange_function. (cmp_equal, cmp_not_equal, cmp_less, cmp_greater, cmp_less_equal) (cmp_greater_equal, in_range): Guard behind __cpp_lib_integer_comparison_functions. (to_underlying): Guard behind __cpp_lib_to_underlying. (unreachable): Guard behind __cpp_lib_unreachable. * include/std/type_traits: Switch to bits/version.h for __cpp_lib_is_{null_pointer,final,nothrow_convertible,aggregate}, __cpp_lib_is_{constant_evaluated,invocable,layout_compatible}, __cpp_lib_is_{pointer_interconvertible,scoped_enum,swappable}, __cpp_lib_{logical_traits,reference_from_temporary,remove_cvref}, __cpp_lib_{result_of_sfinae,transformation_trait_aliases}, __cpp_lib_{type_identity,type_trait_variable_templates}, __cpp_lib_{unwrap_ref,void_t,integral_constant_callable}, __cpp_lib_{bool_constant,bounded_array_traits}, and __cpp_lib_has_unique_object_representations. (integral_constant::operator()): Guard behind __cpp_lib_integral_constant_callable. (bool_constant): Guard behind __cpp_lib_bool_constant. (conjunction, disjunction, negation, conjunction_v, disjunction_v) (negation_v): Guard behind __cpp_lib_logical_traits. (is_null_pointer): Guard behind __cpp_lib_is_null_pointer. (is_final): Guard behind __cpp_lib_is_final. (is_nothrow_convertible, is_nothrow_convertible_v): Guard behind __cpp_lib_is_nothrow_convertible. (remove_const_t, remove_volatile_t, remove_cv_t) (add_const_t, add_volatile_t, add_cv_t): Guard behind __cpp_lib_transformation_trait_aliases. (void_t): Guard behind __cpp_lib_void_t. (is_swappable_with_v, is_nothrow_swappable_with_v) (is_swappable_with, is_nothrow_swappable_with): Guard behind __cpp_lib_is_swappable. (is_nothrow_invocable_r, is_invocable_r, invoke_result) (is_invocable, invoke_result_t): Guard behind __cpp_lib_is_invocable. (alignment_of_v, extent_v, has_virtual_destructor_v) (is_abstract_v, is_arithmetic_v, is_array_v) (is_assignable_v, is_base_of_v, is_class_v, is_compound_v) (is_constructible_v, is_const_v, is_convertible_v) (is_copy_assignable_v, is_copy_constructible_v) (is_default_constructible_v, is_destructible_v) (is_empty_v, is_enum_v, is_final_v, is_floating_point_v) (is_function_v, is_fundamental_v, is_integral_v) (is_invocable_r_v, is_invocable_v, is_literal_type_v) (is_lvalue_reference_v, is_member_function_pointer_v) (is_member_object_pointer_v, is_member_pointer_v) (is_move_assignable_v, is_move_constructible_v) (is_nothrow_assignable_v, is_nothrow_constructible_v) (is_nothrow_copy_assignable_v, is_nothrow_copy_constructible_v) (is_nothrow_default_constructible_v, is_nothrow_destructible_v) (is_nothrow_invocable_r_v, is_nothrow_invocable_v) (is_nothrow_move_assignable_v, is_nothrow_move_constructible_v) (is_null_pointer_v, is_object_v, is_pod_v, is_pointer_v) (is_polymorphic_v, is_reference_v, is_rvalue_reference_v) (is_same_v, is_scalar_v, is_signed_v, is_standard_layout_v) (is_trivially_assignable_v, is_trivially_constructible_v) (is_trivially_copyable_v, is_trivially_copy_assignable_v) (is_trivially_copy_constructible_v) (is_trivially_default_constructible_v) (is_trivially_destructible_v, is_trivially_move_assignable_v) (is_trivially_move_constructible_v, is_trivial_v, is_union_v) (is_unsigned_v, is_void_v, is_volatile_v, rank_v, as variadic): Guard behind __cpp_lib_type_trait_variable_templates. (has_unique_object_representations) (has_unique_object_representations_v): Guard behind __cpp_lib_has_unique_object_representation. (is_aggregate): Guard behind __cpp_lib_is_aggregate. (remove_cvref, remove_cvref_t): Guard behind __cpp_lib_remove_cvref. (type_identity, type_identity_t): Guard behind __cpp_lib_type_identity. (unwrap_reference, unwrap_reference_t, unwrap_ref_decay) (unwrap_ref_decay_t): Guard behind __cpp_lib_unwrap_ref. (is_bounded_array_v, is_unbounded_array_v, is_bounded_array) (is_unbounded_array): Guard behind __cpp_lib_bounded_array_traits. (is_scoped_enum, is_scoped_enum_v): Guard behind __cpp_lib_is_scoped_enum. (reference_constructs_from_temporary) (reference_constructs_from_temporary_v): Guard behind __cpp_lib_reference_from_temporary. * include/std/tuple: Switch to bits/version.h for __cpp_lib_{constexpr_tuple,tuple_by_type,apply_make_from_tuple}. (get<T>): Guard behind __cpp_lib_tuple_by_type. (apply): Guard behind __cpp_lib_apply. (make_from_tuple): Guard behind __cpp_lib_make_from_tuple. * include/std/syncstream: Switch to bits/version.h for __cpp_lib_syncbuf. Guard header behind that FTM. * include/std/string_view: Switch to bits/version.h for __cpp_lib_{string_{view,contains},constexpr_string_view} and __cpp_lib_starts_ends_with. (basic_string_view::starts_with, basic_string_view::ends_with): Guard behind __cpp_lib_starts_ends_with. [C++23 && _GLIBCXX_HOSTED && !defined(__cpp_lib_string_contains)]: Assert as impossible ithout a bug in C++23. * include/std/string: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/thread: Switch to bits/version.h for __cpp_lib_jthread. * include/std/stop_token: Switch to bits/version.h for __cpp_lib_jthread. * include/std/spanstream: Switch to bits/version.h for __cpp_lib_spanstream. Guard header behind that FTM. * include/std/span: Switch to bits/version.h for __cpp_lib_span. Guard header behind that FTM. * include/std/source_location: Switch to bits/version.h for __cpp_lib_source_location. Guard header with that FTM. * include/std/shared_mutex: Switch to bits/version.h for __cpp_lib_shared{,_timed}_mutex. (shared_mutex): Guard behind __cpp_lib_shared_mutex. * include/std/semaphore: Switch to bits/version.h for __cpp_lib_semaphore. Guard header behind that FTM. * include/std/ranges: Switch to bits/version.h for __cpp_lib_ranges_{zip,chunk{,_by},slide,join_with}, __cpp_lib_ranges_{repeat_stride,cartesian_product,as_rvalue}, and __cpp_lib_ranges_{as_const,enumerate,iota}. (ranges::zip et al, ranges::chunk et al, ranges::slide et al) (ranges::chunk_by et al, ranges::join_with et al) (ranges::stride et al, ranges::cartesian_product et al) (ranges::as_rvalue et al, ranges::as_const et al) (ranges::enumerate et al): Guard behind appropriate FTM. * include/std/optional: Switch to bits/version.h for __cpp_lib_optional. Guard header behind that FTM. * include/std/numeric: Switch to bits/version.h for __cpp_lib_{gcd{,_lcm},lcm,constexpr_numeric,interpolate} and __cpp_lib_parallel_algorithm. (gcd, lcm): Guard behind __cpp_lib_gcd_lcm. (midpoint): Guard behind __cpp_lib_interpolate. * include/std/numbers: Switch to bits/version.h for __cpp_lib_math_constants. Guard header behind that FTM. * include/std/mutex: Switch to bits/version.h for __cpp_lib_scoped_lock. (scoped_Lock): Guard behind __cpp_lib_scoped_lock. * include/std/memory_resource: Switch to bits/version.h for __cpp_lib_{polymorphic_allocator,memory_resource}. (synchronized_pool_resource): Guard behind __cpp_lib_memory_resource >= 201603L. (polymorphic_allocator): Guard behind __cpp_lib_polymorphic_allocator. * include/std/memory: Switch to bits/version.h for __cpp_lib_{parallel_algorithm,atomic_value_initialization}. * include/std/list: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/latch: Switch to bits/version.h for __cpp_lib_latch. Guard header behind that FTM. * include/std/iterator: Switch to bits/version.h for __cpp_lib_null_iterators. * include/std/iomanip: Switch to bits/version.h for __cpp_lib_quoted_string_io. (quoted): Guard behind __cpp_lib_quoted_string_io. * include/std/functional: Switch to bits/version.h for __cpp_lib_{invoke{,_r},constexpr_functional,bind_front} and __cpp_lib_{not_fn,booyer_moore_searcher}. (invoke): Guard behind __cpp_lib_invoke. (invoke_r): Guard behind __cpp_lib_invoke_r. (bind_front): Guard behind __cpp_lib_bind_front. (not_fn): Guard behind __cpp_lib_not_fn. (boyer_moore_searcher, boyer_moore_horspool_searcher): Guard definition behind __cpp_lib_boyer_moore_searcher. * include/std/forward_list: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/format: Switch to bits/version.h for __cpp_lib_format. Guard header behind that FTM. * include/std/filesystem: Switch to bits/version.h for __cpp_lib_filesystem. Guard header behind that FTM. * include/std/expected: Switch to bits/version.h for __cpp_lib_expected. Guard header behind it. * include/std/execution: Switch to bits/version.h for __cpp_lib_{execution,parallel_algorithm}. Guard header behind either. * include/std/deque: Switch to bits/version.h for __cpp_lib_erase_if. (erase, erase_if): Guard behind __cpp_lib_erase_if. * include/std/coroutine: Switch to bits/version.h for __cpp_lib_coroutine. Guard header behind that FTM. * include/std/concepts: Switch to bits/version.h for __cpp_lib_concepts. Guard header behind that FTM. * include/std/complex: Switch to bits/version.h for __cpp_lib_{complex_udls,constexpr_complex}. (operator""if, operator""i, operator""il): Guard behind __cpp_lib_complex_udls. * include/std/charconv: Swtich to bits/version.h for __cpp_lib_{to_chars,constexpr_charconv}. * include/std/bitset: Switch to bits/version.h for __cpp_lib_constexpr_bitset. * include/std/bit: Switch to bits/version.h for __cpp_lib_{bit_cast,byteswap,bitops,int_pow2,endian}. (bit_cast): Guard behind __cpp_lib_bit_cast. (byteswap): Guard behind __cpp_lib_byteswap. (rotl, rotr, countl_zero, countl_one, countr_zero, countr_one) (popcount): Guard behind __cpp_lib_bitops. (has_single_bit, bit_ceil, bit_floor, bit_width): Guard behind __cpp_lib_int_pow2. (endian): Guard behind __cpp_lib_endian. * include/std/barrier: Switch to bits/version.h for __cpp_lib_barrier. Guard header behind that FTM. * include/std/atomic: Switch to bits/version.h for __cpp_lib_atomic_{is_always_lock_free,float,ref} and __cpp_lib_lock_free_type_aliases. (*::is_always_lock_free): Guard behind __cpp_lib_atomic_is_always_lock_free. (atomic<float>): Guard behind __cpp_lib_atomic_float. (atomic_ref): Guard behind __cpp_lib_atomic_ref. (atomic_signed_lock_free, atomic_unsigned_lock_free): Guard behind __cpp_lib_atomic_lock_free_type_aliases. * include/std/array: Switch to bits/version.h for __cpp_lib_to_array. (to_array): Guard behind __cpp_lib_to_array. * include/std/any: Switch to bits/version.h for __cpp_lib_any. Guard header behind that FTM. * include/std/algorithm: Switch to bits/version.h for __cpp_lib_parallel_algorithm. * include/c_global/cstddef: Switch to bits/version.h for __cpp_lib_byte. (byte): Guard behind __cpp_lib_byte. * include/c_global/cmath: Switch to bits/version.h for __cpp_lib_{hypot,interpolate}. (hypot3): Guard behind __cpp_lib_hypot. (lerp): Guard behind __cpp_lib_interpolate. * include/c_compatibility/stdatomic.h: Switch to bits/stl_version.h for __cpp_lib_atomic. Guard header behind that FTM. * include/bits/utility.h: Switch to bits/version.h for __cpp_lib_{tuple_element_t,integer_sequence,ranges_zip}. (tuple_element_t): Guard behind __cpp_lib_tuple_element_t. (integer_sequence et al): Guard behind __cpp_lib_integer_sequence. * include/bits/uses_allocator_args.h: Switch to bits/version.h for __cpp_lib_make_obj_using_allocator. Guard header behind that FTM. * include/bits/unordered_map.h: Switch to bits/version.h for __cpp_lib_unordered_map_try_emplace. (try_emplace): Guard behind __cpp_lib_unordered_map_try_emplace. * include/bits/unique_ptr.h: Switch to bits/version.h for __cpp_lib_{constexpr_memory,make_unique}. (make_unique): Guard behind __cpp_lib_make_unique. * include/bits/stl_vector.h: Switch to bits/version.h for __cpp_lib_constexpr_vector. * include/bits/stl_uninitialized.h: Switch to bits/version.h for __cpp_lib_raw_memory_algorithms. (uninitialized_default_construct) (uninitialized_default_construct_n, uninitialized_move) (uninitialized_move_n, uninitialized_value_construct) (uninitialized_value_construct_n): Guard behind __cpp_lib_raw_memory_algorithms. * include/bits/stl_tree.h: Switch to bits/version.h for __cpp_lib_generic_associative_lookup. * include/bits/stl_stack.h: Switch to bits/version.h for __cpp_lib_adaptor_iterator_pair_constructor. (stack): Guard iterator-pair constructor behind __cpp_lib_adaptor_iterator_pair_constructor. * include/bits/stl_queue.h: Switch to bits/version.h for __cpp_lib_adaptor_iterator_pair_constructor. (queue): Guard iterator-pair constructor behind __cpp_lib_adaptor_iterator_pair_constructor. * include/bits/stl_pair.h: Switch to bits/version.h for __cpp_lib_{concepts,tuples_by_type}. (get): Guard type-getting overloads behind __cpp_lib_tuples_by_type. * include/bits/stl_map.h: Switch to bits/version.h for __cpp_lib_map_try_emplace. (map<>::try_emplace): Guard behind __cpp_lib_map_try_emplace. * include/bits/stl_list.h: Switch to bits/version.h for __cpp_lib_list_remove_return_type. (__remove_return_type, _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG) [C++20]: guard behind __cpp_lib_list_remove_return_type instead. * include/bits/stl_iterator.h: Switch to bits/version.h for __cpp_lib_{constexpr_iterator,array_constexpr} and __cpp_lib_{make_reverse_iterator,move_iterator_concept}. (make_reverse_iterator): Guard behind __cpp_lib_make_reverse_iterator. (iterator_concept et al): Guard __cpp_lib_move_iterator_concept changes behind that FTM. * include/bits/stl_function.h: Switch to bits/version.h for __cpp_lib_transparent_operators. (equal_to, not_equal_to, greater, less, greater_equal) (less_equal, bit_and, bit_or, bit_xor, bit_not, logical_and) (logical_or, logical_not, plus, minus, multiplies, divides) (modulus, negate): Guard '= void' fwdecls behind __cpp_lib_transparent_operators. (plus<void>, minus<void>, multiplies<void>, divides<void>) (modulus<void>, negate<void>, logical_and<void>, logical_or<void>) (logical_not<void>, bit_and<void>, bit_or<void>, bit_xor<void>) (equal_to<void>, not_equal_to<void>, greater<void>, less<void>) (greater_equal<void>, less_equal<void>, bit_not<void>) (__has_is_transparent): Guard behind __cpp_lib_transparent_operators. * include/bits/stl_algobase.h: Switch to bits/version.h for __cpp_lib_robust_nonmodifying_seq_ops. (robust equal, mismatch): Guard behind __cpp_lib_nonmember_container_access. * include/bits/stl_algo.h: Swtich to bits/version.h for __cpp_lib_{clamp,sample}. (clamp): Guard behind __cpp_lib_clamp. (sample): Guard behind __cpp_lib_sample. * include/bits/specfun.h: Switch to bits/version.h for __cpp_lib_math_special_functions and __STDCPP_MATH_SPEC_FUNCS__. * include/bits/shared_ptr_base.h: Switch to bits/version.h for __cpp_lib_{smart_ptr_for_overwrite,shared_ptr_arrays}. (_Sp_overwrite_tag): Guard behind __cpp_lib_smart_ptr_for_overwrite. * include/bits/shared_ptr_atomic.h: Switch to bits/version.h for __cpp_lib_atomic_shared_ptr. * include/bits/shared_ptr.h: Switch to bits/version.h for __cpp_lib_{enable_shared_from_this,shared_ptr_weak_type}. (shared_ptr<T>::weak_type): Guard behind __cpp_lib_shared_ptr_weak_type. (enable_shared_from_this<T>::weak_from_this): Guard behind __cpp_lib_enable_shared_from_this. * include/bits/ranges_cmp.h: Switch to bits/version.h for __cpp_lib_ranges. * include/bits/ranges_algo.h: Switch to bits/version.h for __cpp_lib_{shift,ranges_{contains,find_last,fold,iota}}. * include/bits/range_access.h: Switch to bits/version.h for __cpp_lib_nonmember_container_access (size, empty, data): Guard behind __cpp_lib_nonmember_container_access. (ssize): Guard behind __cpp_lib_ssize. * include/bits/ptr_traits.h: Switch to bits/version.h. for __cpp_lib_{constexpr_memory,to_address}. (to_address): Guard behind __cpp_lib_to_address. * include/bits/node_handle.h: Switch to bits/version.h for __cpp_lib_node_extract. Guard header behind that FTM. * include/bits/move_only_function.h: Switch to bits/version.h for __cpp_lib_move_only_function. Guard header behind that FTM. * include/bits/move.h: Switch to bits/version.h for __cpp_lib_addressof_constexpr. * include/bits/ios_base.h: Switch to bits/version.h for __cpp_lib_ios_noreplace. (noreplace): Guard with __cpp_lib_ios_noreplace. * include/bits/hashtable.h: Switch to bits/version.h for __cpp_lib_generic_unordered_lookup. (_M_equal_range_tr, _M_count_tr, _M_find_tr): Guard behind __cpp_lib_generic_unordered_lookup. * include/bits/forward_list.h: Switch to bits/version.h for __cpp_lib_list_remove_return_type. (__remove_return_type): Guard behind __cpp_lib_list_remove_return_type. * include/bits/erase_if.h: Switch to bits/version.h for __cpp_lib_erase_if. * include/bits/cow_string.h: Switch to bits/version.h for __cpp_lib_constexpr_string. * include/bits/chrono.h: Swtich to bits/version.h for __cpp_lib_chrono{,_udls}. (ceil): Guard behind __cpp_lib_chrono. (operator""ns et al): Guard behind __cpp_lib_chrono_udls. * include/bits/char_traits.h: Switch to bits/version.h for __cpp_lib_constexpr_char_traits. * include/bits/basic_string.h: Switch to bits/version.h for __cpp_lib_{constexpr_string,string_{resize_and_overwrite,udls}}. (resize_and_overwrite): Guard behind __cpp_lib_string_resize_and_overwrite. (operator""s): Guard behind __cpp_lib_string_udls. * include/bits/atomic_wait.h: Switch to bits/version.h for __cpp_lib_atomic_wait. Guard header behind that FTM. * include/bits/atomic_base.h: Switch to bits/version.h for __cpp_lib_atomic_value_initialization and __cpp_lib_atomic_flag_test. (atomic_flag::test): Guard behind __cpp_lib_atomic_flag_test, rather than C++20. * include/bits/allocator.h: Switch to bits/version.h for __cpp_lib_incomplete_container_elements. * include/bits/alloc_traits.h: Switch to using bits/version.h for __cpp_lib_constexpr_dynamic_alloc and __cpp_lib_allocator_traits_is_always_equal. * include/bits/align.h: Switch to bits/version.h for defining __cpp_lib_assume_aligned. (assume_aligned): Guard with __cpp_lib_assume_aligned. * include/bits/algorithmfwd.h: Switch to bits/version.h for defining __cpp_lib_constexpr_algorithms. * include/std/stacktrace: Switch to bits/version.h for __cpp_lib_stacktrace. Guard header behind that FTM. * testsuite/23_containers/array/tuple_interface/get_neg.cc: Update line numbers.
2023-04-27 21:03:15 +02:00
#include <bits/version.h>
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
#if __glibcxx_move_only_function || __glibcxx_copyable_function || __glibcxx_function_ref
#include <bits/invoke.h>
#include <bits/utility.h>
libstdc++: Make function_ref non-dangling for stateless wrappers This patch makes the function_ref non-dangling for the stateless wrappers: * any functor for which operator() selected for arguments is static, * standard functors, including pre-C++20 ones. In other words, any function_ref fr, that is constructed from stateless wrapper w, can be still called after the object w is destroyed, e.g.: std::function_ref<bool(int, int)> fr(std::ranges::less{}); fr(1, 2); // OK, previously UB because fr referred to already destroyed // temporary As function_ref's operator() is not constexpr, we test the change by checking if the above declaration can be made constexpr, as such variable cannot contain dangling pointer values. We adjust the function_ref generic constructor from any functor, to use more specialized invoker: * _S_static (newly added) if the called operator() overload is static, after changes r16-5624-g0ea9d760fbf44c, this covers all post-c++20 functors; * _S_nttp<_Fd{}> for pre-C++20 standard functors. In both above cases the value of _M_ptrs is ignored and simply set to nullptr. This follows same technique (checking _Fd::operator()(args...)), and support the same set of types, as for one used for the transform views iterators in r16-5625-g9ed821d107f7a1. As after this change we provide well-defined behavior for the code, that previous was undefined, this changes is pure quality-of-implementation. As illustrated by the test cases, it has observable side effects, where non-longer dangling constructs can be used to define constexpr function_ref. However, the standard does not define when the constructors defined constexpr are actually usable at compile time, and the already have precedent in form of SSO string for validity such constructs being implementation specific. libstdc++-v3/ChangeLog: * include/bits/funcref_impl.h (function_ref::function_ref(_Fn&&)): Use _S_static and _S_nttp invokers. * include/bits/funcwrap.h (_Base_invoker::_S_static): Define. * include/bits/stl_function.h (std::__is_std_op_template) (std::__is_std_op_wrapper) [__cplusplus > 201703L]: Moved from std/ranges. * include/std/ranges (__detail::__is_std_op_template) (__detail::__is_std_op_wrapper): Moved to bits/stl_function.h. * testsuite/20_util/function_ref/dangling.cc: New test. * testsuite/20_util/function_ref/dangling_neg.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2026-02-02 10:19:51 +01:00
#if __glibcxx_function_ref
#include <bits/stl_function.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
template<typename _Tp>
inline constexpr bool __is_polymorphic_function_v = false;
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
namespace __polyfunc
{
union _Ptrs
{
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
const void* _M_obj;
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
void (*_M_func)();
};
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
template<typename _Tp>
[[__gnu__::__always_inline__]]
constexpr auto*
__cast_to(_Ptrs __ptrs) noexcept
{
using _Td = remove_reference_t<_Tp>;
if constexpr (is_function_v<_Td>)
return reinterpret_cast<_Td*>(__ptrs._M_func);
else if constexpr (is_const_v<_Td>)
return static_cast<_Td*>(__ptrs._M_obj);
else
return static_cast<_Td*>(const_cast<void*>(__ptrs._M_obj));
}
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
struct _Storage
{
void* _M_addr() noexcept { return &_M_bytes[0]; }
void const* _M_addr() const noexcept { return &_M_bytes[0]; }
template<typename _Tp>
static consteval bool
_S_stored_locally() noexcept
{
return sizeof(_Tp) <= sizeof(_Storage)
&& alignof(_Tp) <= alignof(_Storage)
&& is_nothrow_move_constructible_v<_Tp>;
}
template<typename _Tp, typename... _Args>
static consteval bool
_S_nothrow_init() noexcept
{
if constexpr (_S_stored_locally<_Tp>())
return is_nothrow_constructible_v<_Tp, _Args...>;
return false;
}
template<typename _Tp, typename... _Args>
void
_M_init(_Args&&... __args) noexcept(_S_nothrow_init<_Tp, _Args...>())
{
if constexpr (is_function_v<remove_pointer_t<_Tp>>)
{
static_assert( sizeof...(__args) <= 1 );
// __args can have up to one element, returns nullptr if empty.
_Tp __func = (nullptr, ..., __args);
_M_ptrs._M_func = reinterpret_cast<void(*)()>(__func);
}
else if constexpr (!_S_stored_locally<_Tp>())
_M_ptrs._M_obj = new _Tp(std::forward<_Args>(__args)...);
else
::new (_M_addr()) _Tp(std::forward<_Args>(__args)...);
}
// We want to have enough space to store a simple delegate type.
struct _Delegate { void (_Storage::*__pfm)(); _Storage* __obj; };
union {
_Ptrs _M_ptrs;
alignas(_Delegate) alignas(void(*)())
unsigned char _M_bytes[sizeof(_Delegate)];
};
};
template<bool _Noex, typename _Ret, typename... _Args>
struct _Base_invoker
{
using _Signature = _Ret(*)(_Args...) noexcept(_Noex);
using __storage_func_t = _Ret(*)(const _Storage&, _Args...) noexcept(_Noex);
template<typename _Tp>
static consteval __storage_func_t
_S_storage()
{ return &_S_call_storage<_Adjust_target<_Tp>>; }
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
using __ptrs_func_t = _Ret(*)(_Ptrs, _Args...) noexcept(_Noex);
template<typename _Tp>
static consteval __ptrs_func_t
_S_ptrs()
{ return &_S_call_ptrs<_Adjust_target<_Tp>>; }
#ifdef __glibcxx_function_ref // C++ >= 26
libstdc++: Make function_ref non-dangling for stateless wrappers This patch makes the function_ref non-dangling for the stateless wrappers: * any functor for which operator() selected for arguments is static, * standard functors, including pre-C++20 ones. In other words, any function_ref fr, that is constructed from stateless wrapper w, can be still called after the object w is destroyed, e.g.: std::function_ref<bool(int, int)> fr(std::ranges::less{}); fr(1, 2); // OK, previously UB because fr referred to already destroyed // temporary As function_ref's operator() is not constexpr, we test the change by checking if the above declaration can be made constexpr, as such variable cannot contain dangling pointer values. We adjust the function_ref generic constructor from any functor, to use more specialized invoker: * _S_static (newly added) if the called operator() overload is static, after changes r16-5624-g0ea9d760fbf44c, this covers all post-c++20 functors; * _S_nttp<_Fd{}> for pre-C++20 standard functors. In both above cases the value of _M_ptrs is ignored and simply set to nullptr. This follows same technique (checking _Fd::operator()(args...)), and support the same set of types, as for one used for the transform views iterators in r16-5625-g9ed821d107f7a1. As after this change we provide well-defined behavior for the code, that previous was undefined, this changes is pure quality-of-implementation. As illustrated by the test cases, it has observable side effects, where non-longer dangling constructs can be used to define constexpr function_ref. However, the standard does not define when the constructors defined constexpr are actually usable at compile time, and the already have precedent in form of SSO string for validity such constructs being implementation specific. libstdc++-v3/ChangeLog: * include/bits/funcref_impl.h (function_ref::function_ref(_Fn&&)): Use _S_static and _S_nttp invokers. * include/bits/funcwrap.h (_Base_invoker::_S_static): Define. * include/bits/stl_function.h (std::__is_std_op_template) (std::__is_std_op_wrapper) [__cplusplus > 201703L]: Moved from std/ranges. * include/std/ranges (__detail::__is_std_op_template) (__detail::__is_std_op_wrapper): Moved to bits/stl_function.h. * testsuite/20_util/function_ref/dangling.cc: New test. * testsuite/20_util/function_ref/dangling_neg.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2026-02-02 10:19:51 +01:00
template<typename _Fn>
static _Ret
_S_static(_Ptrs, _Args... __args) noexcept(_Noex)
{ return _Fn::operator()(std::forward<_Args>(__args)...); }
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
template<auto __fn>
static _Ret
_S_nttp(_Ptrs, _Args... __args) noexcept(_Noex)
{ return std::__invoke_r<_Ret>(__fn, std::forward<_Args>(__args)...); }
template<auto __fn, typename _Tp>
static _Ret
_S_bind_ptr(_Ptrs __ptrs, _Args... __args) noexcept(_Noex)
{
auto* __p = __polyfunc::__cast_to<_Tp>(__ptrs);
return std::__invoke_r<_Ret>(__fn, __p,
std::forward<_Args>(__args)...);
}
template<auto __fn, typename _Ref>
static _Ret
_S_bind_ref(_Ptrs __ptrs, _Args... __args) noexcept(_Noex)
{
auto* __p = __polyfunc::__cast_to<_Ref>(__ptrs);
return std::__invoke_r<_Ret>(__fn, static_cast<_Ref>(*__p),
std::forward<_Args>(__args)...);
}
#endif // __glibcxx_function_ref
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
private:
template<typename _Tp, typename _Td = remove_cvref_t<_Tp>>
using _Adjust_target =
__conditional_t<is_pointer_v<_Td> || is_member_pointer_v<_Td>, _Td, _Tp>;
template<typename _Tp>
static _Ret
_S_call_storage(const _Storage& __ref, _Args... __args) noexcept(_Noex)
{
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
_Ptrs __ptrs;
if constexpr (is_function_v<remove_pointer_t<_Tp>>)
__ptrs._M_func = __ref._M_ptrs._M_func;
else if constexpr (!_Storage::_S_stored_locally<remove_cvref_t<_Tp>>())
__ptrs._M_obj = __ref._M_ptrs._M_obj;
else
__ptrs._M_obj = __ref._M_addr();
return _S_call_ptrs<_Tp>(__ptrs, std::forward<_Args>(__args)...);
}
template<typename _Tp>
static _Ret
_S_call_ptrs(_Ptrs __ptrs, _Args... __args) noexcept(_Noex)
{
if constexpr (is_function_v<remove_pointer_t<_Tp>>)
return std::__invoke_r<_Ret>(reinterpret_cast<_Tp>(__ptrs._M_func),
std::forward<_Args>(__args)...);
else
{
auto* __p = __polyfunc::__cast_to<_Tp>(__ptrs);
return std::__invoke_r<_Ret>(static_cast<_Tp>(*__p),
std::forward<_Args>(__args)...);
}
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
}
};
template<typename _Tp>
libstdc++: Pass small trivial types by value in polymorphic wrappers This patch adjust the passing of parameters for the move_only_function, copyable_function and function_ref. For types that are declared as being passed by value in signature template argument, they are passed by value to the invoker, when they are small (at most two pointers), trivially move constructible and trivially destructible. The latter guarantees that passing them by value has not user visible side effects. In particular, this extends the set of types forwarded by value, that was previously limited to scalars, to also include specializations of std::span and std::string_view, and similar standard and program defined-types. Checking the suitability of the parameter types requires the types to be complete. As a consequence, the implementation imposes requirements on instantiation of move_only_function and copyable_function. To avoid producing the errors from the implementation details, a static assertion was added to partial specializations of copyable_function, move_only_function and function_ref. The static assertion uses existing __is_complete_or_unbounded, as arrays type parameters are automatically decayed in function type. Standard already specifies in [res.on.functions] p2.5 that instantiating these partial specialization with incomplete types leads to undefined behavior. libstdc++-v3/ChangeLog: * include/bits/funcwrap.h (__polyfunc::__pass_by_rref): Define. (__polyfunc::__param_t): Update to use __pass_by_rref. * include/bits/cpyfunc_impl.h:: Assert that are parameters type are complete. * include/bits/funcref_impl.h: Likewise. * include/bits/mofunc_impl.h: Likewise. * testsuite/20_util/copyable_function/call.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/move_only_function/call.cc: New test. * testsuite/20_util/copyable_function/conv.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/copyable_function/incomplete_neg.cc: New test. * testsuite/20_util/function_ref/incomplete_neg.cc: New test. * testsuite/20_util/move_only_function/incomplete_neg.cc: New test. Reviewed-by: Patrick Palka <ppalka@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-28 11:16:22 +02:00
consteval bool
__pass_by_value()
{
// n.b. sizeof(Incomplete&) is ill-formed for incomplete types,
// so we check is_reference_v first.
if constexpr (is_reference_v<_Tp> || is_scalar_v<_Tp>)
return true;
else
// n.b. we already asserted that types are complete in wrappers,
// avoid triggering additional errors from this function.
if constexpr (std::__is_complete_or_unbounded(__type_identity<_Tp>()))
if constexpr (sizeof(_Tp) <= 2 * sizeof(void*))
return is_trivially_move_constructible_v<_Tp>
&& is_trivially_destructible_v<_Tp>;
return false;
}
template<typename _Tp>
using __param_t = __conditional_t<__pass_by_value<_Tp>(), _Tp, _Tp&&>;
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
template<bool _Noex, typename _Ret, typename... _Args>
using _Invoker = _Base_invoker<_Noex, remove_cv_t<_Ret>, __param_t<_Args>...>;
template<typename _Func>
auto&
__invoker_of(_Func& __f) noexcept
{ return __f._M_invoke; }
template<typename _Func>
auto&
__base_of(_Func& __f) noexcept
{ return static_cast<__like_t<_Func&, typename _Func::_Base>>(__f); }
template<typename _Src, typename _Dst>
consteval bool
__is_invoker_convertible() noexcept
{
if constexpr (requires { typename _Src::_Signature; })
return is_convertible_v<typename _Src::_Signature,
typename _Dst::_Signature>;
else
return false;
}
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
#if __glibcxx_move_only_function || __glibcxx_copyable_function
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
struct _Manager
{
enum class _Op
{
// saves address of entity in *__src to __target._M_ptrs,
_Address,
// moves entity stored in *__src to __target, __src becomes empty
_Move,
// copies entity stored in *__src to __target, supported only if
// _ProvideCopy is specified.
_Copy,
// destroys entity stored in __target, __src is ignoring
_Destroy,
};
// A function that performs operation __op on the __target and possibly __src.
libstdc++: Implement C++26 copyable_function [PR119125] This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12 10:01:22 +02:00
using _Func = void (*)(_Op __op, _Storage& __target, const _Storage* __src);
// The no-op manager function for objects with no target.
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
static void _S_empty(_Op, _Storage&, const _Storage*) noexcept { }
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
template<bool _ProvideCopy, typename _Tp>
consteval static auto
_S_select()
{
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
if constexpr (is_function_v<remove_pointer_t<_Tp>>)
return &_S_func;
else if constexpr (!_Storage::_S_stored_locally<_Tp>())
return &_S_ptr<_ProvideCopy, _Tp>;
else if constexpr (is_trivially_copyable_v<_Tp>)
return &_S_trivial;
else
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
return &_S_local<_ProvideCopy, _Tp>;
}
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
private:
static void
_S_func(_Op __op, _Storage& __target, const _Storage* __src) noexcept
{
switch (__op)
{
case _Op::_Address:
case _Op::_Move:
case _Op::_Copy:
__target._M_ptrs._M_func = __src->_M_ptrs._M_func;
return;
case _Op::_Destroy:
return;
}
}
static void
_S_trivial(_Op __op, _Storage& __target, const _Storage* __src) noexcept
{
switch (__op)
{
case _Op::_Address:
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
__target._M_ptrs._M_obj = __src->_M_addr();
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
return;
case _Op::_Move:
case _Op::_Copy:
// N.B. Creating _Storage starts lifetime of _M_bytes char array,
// that implicitly creates, amongst other, all possible trivially
// copyable objects, so we copy any object present in __src._M_bytes.
::new (&__target) _Storage(*__src);
return;
case _Op::_Destroy:
return;
}
}
template<bool _Provide_copy, typename _Tp>
static void
_S_local(_Op __op, _Storage& __target, const _Storage* __src)
noexcept(!_Provide_copy)
{
switch (__op)
{
case _Op::_Address:
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
__target._M_ptrs._M_obj = __src->_M_addr();
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
return;
case _Op::_Move:
{
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
_Tp* __obj = static_cast<_Tp*>(const_cast<void*>(__src->_M_addr()));
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
::new(__target._M_addr()) _Tp(std::move(*__obj));
__obj->~_Tp();
}
return;
case _Op::_Destroy:
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
static_cast<_Tp*>(__target._M_addr())->~_Tp();
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
return;
case _Op::_Copy:
if constexpr (_Provide_copy)
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
{
auto* __obj = static_cast<const _Tp*>(__src->_M_addr());
::new (__target._M_addr()) _Tp(*__obj);
return;
}
__builtin_unreachable();
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
}
}
template<bool _Provide_copy, typename _Tp>
static void
_S_ptr(_Op __op, _Storage& __target, const _Storage* __src)
noexcept(!_Provide_copy)
{
switch (__op)
{
case _Op::_Address:
case _Op::_Move:
__target._M_ptrs._M_obj = __src->_M_ptrs._M_obj;
return;
case _Op::_Destroy:
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
delete static_cast<const _Tp*>(__target._M_ptrs._M_obj);
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
return;
case _Op::_Copy:
if constexpr (_Provide_copy)
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
{
auto* __obj = static_cast<const _Tp*>(__src->_M_ptrs._M_obj);
__target._M_ptrs._M_obj = new _Tp(*__obj);
return;
}
__builtin_unreachable();
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
}
}
};
class _Mo_base
{
protected:
_Mo_base() noexcept
: _M_manage(_Manager::_S_empty)
{ }
_Mo_base(_Mo_base&& __x) noexcept
{ _M_move(__x); }
template<typename _Tp, typename... _Args>
static consteval bool
_S_nothrow_init() noexcept
{ return _Storage::_S_nothrow_init<_Tp, _Args...>(); }
template<typename _Tp, typename... _Args>
void
_M_init(_Args&&... __args)
noexcept(_S_nothrow_init<_Tp, _Args...>())
{
_M_storage._M_init<_Tp>(std::forward<_Args>(__args)...);
_M_manage = _Manager::_S_select<false, _Tp>();
}
void
_M_move(_Mo_base& __x) noexcept
{
using _Op = _Manager::_Op;
_M_manage = std::__exchange(__x._M_manage, _Manager::_S_empty);
_M_manage(_Op::_Move, _M_storage, &__x._M_storage);
}
_Mo_base&
operator=(_Mo_base&& __x) noexcept
{
_M_destroy();
_M_move(__x);
return *this;
}
void
_M_reset() noexcept
{
_M_destroy();
_M_manage = _Manager::_S_empty;
}
void _M_destroy() noexcept
{ _M_manage(_Manager::_Op::_Destroy, _M_storage, nullptr); }
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
~_Mo_base()
{ _M_destroy(); }
void
swap(_Mo_base& __x) noexcept
{
using _Op = _Manager::_Op;
// Order of operations here is more efficient if __x is empty.
_Storage __s;
__x._M_manage(_Op::_Move, __s, &__x._M_storage);
_M_manage(_Op::_Move, __x._M_storage, &_M_storage);
__x._M_manage(_Op::_Move, _M_storage, &__s);
std::swap(_M_manage, __x._M_manage);
}
_Manager::_Func _M_manage;
_Storage _M_storage;
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
};
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
#endif // __glibcxx_copyable_function || __glibcxx_copyable_function
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
} // namespace __polyfunc
/// @endcond
libstdc++: Implement C++26 copyable_function [PR119125] This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12 10:01:22 +02:00
#ifdef __glibcxx_move_only_function // C++ >= 23 && HOSTED
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
template<typename... _Signature>
class move_only_function; // not defined
/// @cond undocumented
template<typename _Tp>
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
constexpr bool __is_polymorphic_function_v<move_only_function<_Tp>> = true;
namespace __detail::__variant
{
template<typename> struct _Never_valueless_alt; // see <variant>
// Provide the strong exception-safety guarantee when emplacing a
// move_only_function into a variant.
template<typename... _Signature>
struct _Never_valueless_alt<std::move_only_function<_Signature...>>
: true_type
{ };
} // namespace __detail::__variant
libstdc++: Avoid double indirection in move_only_function when possible [PR119125] Based on the provision in C++26 [func.wrap.general] p2 this patch adjust the generic move_only_function(_Fn&&) constructor, such that when _Fn refers to selected move_only_function instantiations, the ownership of the target object is directly transfered to constructor object. This avoid cost of double indirection in this situation. We apply this also in C++23 mode. We also fix handling of self assignments, to match behavior required by standard, due use of copy and swap idiom. An instantiations MF1 of move_only_function can transfer target of another instantiation MF2, if it can be constructed via usual rules (__is_callable_from<_MF2>), and their invoker are convertible (__is_invoker_convertible<MF2, MF1>()), i.e.: * MF1 is less noexcept than MF2, * return types are the same after stripping cv-quals, * adujsted parameters type are the same (__poly::_param_t), i.e. param of types T and T&& are compatible for non-trivially copyable objects. Compatiblity of cv ref qualification is checked via __is_callable_from<_MF2>. To achieve above the generation of _M_invoke functions is moved to _Invoker class templates, that only depends on noexcept, return type and adjusted parameter of the signature. To make the invoker signature compatible between const and mutable qualified signatures, we always accept _Storage as const& and perform a const_cast for locally stored object. This approach guarantees that we never strip const from const object. Another benefit of this approach is that move_only_function<void(std::string)> and move_only_function<void(std::string&&)> use same funciton pointer, which should reduce binary size. The _Storage and _Manager functionality was also extracted and adjusted from _Mofunc_base, in preparation for implementation for copyable_function and function_ref. The _Storage was adjusted to store functions pointers as void(*)(). The manage function, now accepts _Op enum parameter, and supports additional operations: * _Op::_Address stores address of target object in destination * _Op::_Copy, when enabled, copies from source to destination Furthermore, we provide a type-independent mamange functions for handling all: * function pointer types * trivially copyable object stored locally. Similary as in case of invoker, we always pass source as const (for copy), and cast away constness in case of move operations, where we know that source is mutable. Finally, the new helpers are defined in __polyfunc internal namespace. PR libstdc++/119125 libstdc++-v3/ChangeLog: * include/bits/mofunc_impl.h: (std::move_only_function): Adjusted for changes in bits/move_only_function.h (move_only_function::move_only_function(_Fn&&)): Special case move_only_functions with same invoker. (move_only_function::operator=(move_only_function&&)): Handle self assigment. * include/bits/move_only_function.h (__polyfunc::_Ptrs) (__polyfunc::_Storage): Refactored from _Mo_func::_Storage. (__polyfunc::__param_t): Moved from move_only_function::__param_t. (__polyfunc::_Base_invoker, __polyfunc::_Invoke): Refactored from move_only_function::_S_invoke. (__polyfunc::_Manager): Refactored from _Mo_func::_S_manager. (std::_Mofunc_base): Moved into __polyfunc::_Mo_base with parts extracted to __polyfunc::_Storage and __polyfunc::_Manager. (__polyfunc::__deref_as, __polyfunc::__invoker_of) (__polyfunc::__base_of, __polyfunc::__is_invoker_convertible): Define. (std::__is_move_only_function_v): Renamed to __is_polymorphic_function_v. (std::__is_polymorphic_function_v): Renamed from __is_move_only_function_v. * testsuite/20_util/move_only_function/call.cc: Test for functions pointers. * testsuite/20_util/move_only_function/conv.cc: New test. * testsuite/20_util/move_only_function/move.cc: Tests for self assigment. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-08 08:08:43 +02:00
/// @endcond
libstdc++: Implement C++26 copyable_function [PR119125] This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12 10:01:22 +02:00
#endif // __glibcxx_move_only_function
#ifdef __glibcxx_copyable_function // C++ >= 26 && HOSTED
/// @cond undocumented
namespace __polyfunc
{
class _Cpy_base : public _Mo_base
{
protected:
_Cpy_base() = default;
template<typename _Tp, typename... _Args>
void
_M_init(_Args&&... __args)
noexcept(_S_nothrow_init<_Tp, _Args...>())
{
_M_storage._M_init<_Tp>(std::forward<_Args>(__args)...);
_M_manage = _Manager::_S_select<true, _Tp>();
}
void
_M_copy(_Cpy_base const& __x)
{
using _Op = _Manager::_Op;
__x._M_manage(_Op::_Copy, _M_storage, &__x._M_storage);
_M_manage = __x._M_manage;
}
_Cpy_base(_Cpy_base&&) = default;
_Cpy_base(_Cpy_base const& __x)
: _Mo_base()
libstdc++: Implement C++26 copyable_function [PR119125] This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12 10:01:22 +02:00
{ _M_copy(__x); }
_Cpy_base&
operator=(_Cpy_base&&) = default;
_Cpy_base&
// Needs to use copy and swap for exception guarantees.
operator=(_Cpy_base const&) = delete;
};
} // namespace __polyfunc
/// @endcond
template<typename... _Signature>
class copyable_function; // not defined
template<typename _Tp>
constexpr bool __is_polymorphic_function_v<copyable_function<_Tp>> = true;
namespace __detail::__variant
{
template<typename> struct _Never_valueless_alt; // see <variant>
// Provide the strong exception-safety guarantee when emplacing a
// copyable_function into a variant.
template<typename... _Signature>
struct _Never_valueless_alt<std::copyable_function<_Signature...>>
: true_type
{ };
} // namespace __detail::__variant
#endif // __glibcxx_copyable_function
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
#ifdef __glibcxx_function_ref // C++ >= 26
/// @cond undocumented
namespace __polyfunc
{
template<typename _Sig>
struct __skip_first_arg;
// Additional partial specializations are defined in bits/funcref_impl.h
template<bool _Noex, typename _Ret, typename _Arg, typename... _Args>
struct __skip_first_arg<_Ret(*)(_Arg, _Args...) noexcept(_Noex)>
{ using type = _Ret(_Args...) noexcept(_Noex); };
// Returns a function pointer to signature to be used with function_ref, or void.
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
template<typename _Fn, typename _Tr>
consteval auto
__deduce_funcref()
{
if constexpr (is_member_object_pointer_v<_Fn>)
{
if constexpr (is_invocable_v<_Fn, _Tr>)
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 4425. CTAD function_ref from data member pointer should produce
// noexcept signature
return static_cast<invoke_result_t<_Fn, _Tr>(*)() noexcept>(nullptr);
}
else if constexpr (requires { typename __skip_first_arg<_Fn>::type; })
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
return static_cast<__skip_first_arg<_Fn>::type*>(nullptr);
}
} // namespace __polyfunc
/// @endcond
template<typename... _Signature>
class function_ref; // not defined
template<typename _Fn>
requires is_function_v<_Fn>
function_ref(_Fn*) -> function_ref<_Fn>;
template<auto __f, class _Fn = remove_pointer_t<decltype(__f)>>
requires is_function_v<_Fn>
function_ref(nontype_t<__f>) -> function_ref<_Fn>;
template<auto __f, typename _Tp,
typename _SignaturePtr =
decltype(__polyfunc::__deduce_funcref<decltype(__f), _Tp&>())>
requires (!is_void_v<_SignaturePtr>)
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
function_ref(nontype_t<__f>, _Tp&&)
-> function_ref<remove_pointer_t<_SignaturePtr>>;
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
#endif // __glibcxx_function_ref
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
libstdc++: Implement C++26 copyable_function [PR119125] This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12 10:01:22 +02:00
#ifdef __glibcxx_move_only_function // C++ >= 23 && HOSTED
#include "mofunc_impl.h"
#define _GLIBCXX_MOF_CV const
#include "mofunc_impl.h"
#define _GLIBCXX_MOF_REF &
#include "mofunc_impl.h"
#define _GLIBCXX_MOF_REF &&
#include "mofunc_impl.h"
#define _GLIBCXX_MOF_CV const
#define _GLIBCXX_MOF_REF &
#include "mofunc_impl.h"
#define _GLIBCXX_MOF_CV const
#define _GLIBCXX_MOF_REF &&
#include "mofunc_impl.h"
libstdc++: Only declare feature test macros in standard headers This change moves the definitions of feature test macros (or strictly speaking, the requests for <bits/version.h> to define them) so that only standard headers define them. For example, <bits/shared_ptr.h> will no longer define macros related to std::shared_ptr, only <memory> and <version> will define them. This means that __cpp_lib_shared_ptr_arrays will not be defined by <future> or by other headers that include <bits/shared_ptr.h>. It will only be defined when <memory> has been included. This will discourage users from relying on transitive includes. As a result, internal headers that need to query the macros should use the internal macros like __glibcxx_shared_ptr_arrays instead of __cpp_lib_shared_ptr_arrays, as those internal macros are defined by the internal headers after icluding <bits/version.h>. There are some exceptions to this rule, because __cpp_lib_is_constant_evaluated is defined by bits/c++config.h and so is available everywhere, and __cpp_lib_three_way_comparison is defined by <compare> which several headers are explicitly specified to include, so its macro is guaranteed to be usable too. N.B. not many internal headers actually need an explicit include of <bits/version.h>, because most of them include <type_traits> and so get all the __glibcxx_foo internal macros from there. libstdc++-v3/ChangeLog: * include/bits/algorithmfwd.h: Do not define standard feature test macro here. * include/bits/align.h: Likewise. Test internal macros instead of standard macros. * include/bits/alloc_traits.h: Likewise. * include/bits/allocator.h: Likewise. * include/bits/atomic_base.h: Likewise. * include/bits/atomic_timed_wait.h: Likewise. * include/bits/atomic_wait.h: Likewise. * include/bits/basic_string.h: Likewise. * include/bits/basic_string.tcc: Likewise. * include/bits/char_traits.h: Likewise. * include/bits/chrono.h: Likewise. * include/bits/cow_string.h: Likewise. * include/bits/forward_list.h: Likewise. * include/bits/hashtable.h: Likewise. * include/bits/ios_base.h: Likewise. * include/bits/memory_resource.h: Likewise. * include/bits/move.h: Likewise. * include/bits/move_only_function.h: Likewise. * include/bits/node_handle.h: Likewise. * include/bits/ptr_traits.h: Likewise. * include/bits/range_access.h: Likewise. * include/bits/ranges_algo.h: Likewise. * include/bits/ranges_cmp.h: Likewise. * include/bits/ranges_util.h: Likewise. * include/bits/semaphore_base.h: Likewise. * include/bits/shared_ptr.h: Likewise. * include/bits/shared_ptr_atomic.h: Likewise. * include/bits/shared_ptr_base.h: Likewise. * include/bits/stl_algo.h: Likewise. * include/bits/stl_algobase.h: Likewise. * include/bits/stl_function.h: Likewise. * include/bits/stl_iterator.h: Likewise. * include/bits/stl_list.h: Likewise. * include/bits/stl_map.h: Likewise. * include/bits/stl_pair.h: Likewise. * include/bits/stl_queue.h: Likewise. * include/bits/stl_stack.h: Likewise. * include/bits/stl_tree.h: Likewise. * include/bits/stl_uninitialized.h: Likewise. * include/bits/stl_vector.h: Likewise. * include/bits/unique_ptr.h: Likewise. * include/bits/unordered_map.h: Likewise. * include/bits/uses_allocator_args.h: Likewise. * include/bits/utility.h: Likewise. * include/bits/erase_if.h: Add comment. * include/std/algorithm: Define standard feature test macros here. * include/std/atomic: Likewise. * include/std/array: Likewise. * include/std/chrono: Likewise. * include/std/condition_variable: Likewise. * include/std/deque: Likewise. * include/std/format: Likewise. * include/std/functional: Likewise. * include/std/forward_list: Likewise. * include/std/ios: Likewise. * include/std/iterator: Likewise. * include/std/list: Likewise. * include/std/map: Likewise. * include/std/memory: Likewise. * include/std/numeric: Likewise. * include/std/queue: Likewise. * include/std/ranges: Likewise. * include/std/regex: Likewise. * include/std/set: Likewise. * include/std/stack: Likewise. * include/std/stop_token: Likewise. * include/std/string: Likewise. * include/std/string_view: * include/std/tuple: Likewise. * include/std/unordered_map: * include/std/unordered_set: * include/std/utility: Likewise. * include/std/vector: Likewise. * include/std/scoped_allocator: Query internal macros instead of standard macros.
2023-09-19 17:46:32 +01:00
#endif // __glibcxx_move_only_function
libstdc++: Implement C++26 copyable_function [PR119125] This patch implements C++26 copyable_function as specified in P2548R6. It also implements LWG 4255 that adjust move_only_function so constructing from empty copyable_function, produces empty functor. This falls from existing checks, after specializing __is_polymorphic_function_v for copyable_function specializations. For compatible invoker signatures, the move_only_function may be constructed from copyable_funciton without double indirection. To achieve that we derive _Cpy_base from _Mo_base, and specialize __is_polymorphic_function_v for copyable_function. Similary copyable_functions with compatible signatures can be converted without double indirection. As we starting to use _Op::_Copy operation from the _M_manage function, invocations of that functions may now throw exceptions, so noexcept needs to be removed from the signature of stored _M_manage pointers. This also affects operations in _Mo_base, however we already wrap _M_manage invocations in noexcept member functions (_M_move, _M_destroy, swap). PR libstdc++/119125 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Addded cpyfunc_impl.h header. * include/Makefile.am: Add bits cpyfunc_impl.h. * include/Makefile.in: Add bits cpyfunc_impl.h. * include/bits/cpyfunc_impl.h: New file. * include/bits/mofunc_impl.h: Mention LWG 4255. * include/bits/move_only_function.h: Update header description and change guard to also check __glibcxx_copyable_function. (_Manager::_Func): Remove noexcept. (std::__is_polymorphic_function_v<move_only_function<_Tp>>) (__variant::_Never_valueless_alt<std::move_only_function<_Signature...>>) (move_only_function) [__glibcxx_move_only_function]: Adjust guard. (std::__is_polymorphic_function_v<copyable_function<_Tp>>) (__variant::_Never_valueless_alt<std::copyable_function<_Signature...>>) (__polyfunc::_Cpy_base, std::copyable_function) [__glibcxx_copyable_function]: Define. * include/bits/version.def: Define copyable_function. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_copyable_function. * src/c++23/std.cc.in (copyable_function) [__cpp_lib_copyable_function]: Export. * testsuite/20_util/copyable_function/call.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/cons.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/conv.cc: New test based on move_only_function tests. * testsuite/20_util/copyable_function/copy.cc: New test. * testsuite/20_util/copyable_function/move.cc: New test based on move_only_function tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-12 10:01:22 +02:00
#ifdef __glibcxx_copyable_function // C++ >= 26 && HOSTED
#include "cpyfunc_impl.h"
#define _GLIBCXX_MOF_CV const
#include "cpyfunc_impl.h"
#define _GLIBCXX_MOF_REF &
#include "cpyfunc_impl.h"
#define _GLIBCXX_MOF_REF &&
#include "cpyfunc_impl.h"
#define _GLIBCXX_MOF_CV const
#define _GLIBCXX_MOF_REF &
#include "cpyfunc_impl.h"
#define _GLIBCXX_MOF_CV const
#define _GLIBCXX_MOF_REF &&
#include "cpyfunc_impl.h"
#endif // __glibcxx_copyable_function
libstdc++: Implement C++26 function_ref [PR119126] This patch implements C++26 function_ref as specified in P0792R14, with correction for constraints for constructor accepting nontype_t parameter from LWG 4256. As function_ref may store a pointer to the const object, __Ptrs::_M_obj is changed to const void*, so again we do not cast away const from const objects. To help with necessary casts, a __polyfunc::__cast_to helper is added, that accepts reference to or target type direclty. The _Invoker now defines additional call methods used by function_ref: _S_ptrs() for invoking target passed by reference, and __S_nttp, _S_bind_ptr, _S_bind_ref for handling constructors accepting nontype_t. The existing _S_call_storage is changed to thin wrapper, that initialies _Ptrs, and forwards to _S_call_ptrs. This reduced the most uses of _Storage::_M_ptr and _Storage::_M_ref, so this functions was removed, and _Manager uses were adjusted. Finally we make function_ref available in freestanding mode, as move_only_function and copyable_function are currently only available in hosted, so we define _Manager and _Mo_base only if either __glibcxx_move_only_function or __glibcxx_copyable_function is defined. PR libstdc++/119126 libstdc++-v3/ChangeLog: * doc/doxygen/stdheader.cc: Added funcref_impl.h file. * include/Makefile.am: Added funcref_impl.h file. * include/Makefile.in: Added funcref_impl.h file. * include/bits/funcref_impl.h: New file. * include/bits/funcwrap.h: (_Ptrs::_M_obj): Const-qualify. (_Storage::_M_ptr, _Storage::_M_ref): Remove. (__polyfunc::__cast_to) Define. (_Base_invoker::_S_ptrs, _Base_invoker::_S_nttp) (_Base_invoker::_S_bind_ptrs, _Base_invoker::_S_bind_ref) (_Base_invoker::_S_call_ptrs): Define. (_Base_invoker::_S_call_storage): Foward to _S_call_ptrs. (_Manager::_S_local, _Manager::_S_ptr): Adjust for _M_obj being const qualified. (__polyfunc::_Manager, __polyfunc::_Mo_base): Guard with __glibcxx_move_only_function || __glibcxx_copyable_function. (__polyfunc::__skip_first_arg, __polyfunc::__deduce_funcref) (std::function_ref) [__glibcxx_function_ref]: Define. * include/bits/utility.h (std::nontype_t, std::nontype) (__is_nontype_v) [__glibcxx_function_ref]: Define. * include/bits/version.def: Define function_ref. * include/bits/version.h: Regenerate. * include/std/functional: Define __cpp_lib_function_ref. * src/c++23/std.cc.in (std::nontype_t, std::nontype) (std::function_ref) [__cpp_lib_function_ref]: Export. * testsuite/20_util/function_ref/assign.cc: New test. * testsuite/20_util/function_ref/call.cc: New test. * testsuite/20_util/function_ref/cons.cc: New test. * testsuite/20_util/function_ref/cons_neg.cc: New test. * testsuite/20_util/function_ref/conv.cc: New test. * testsuite/20_util/function_ref/deduction.cc: New test. * testsuite/20_util/function_ref/mutation.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-05-14 12:04:24 +02:00
#ifdef __glibcxx_function_ref // C++ >= 26
#include "funcref_impl.h"
#define _GLIBCXX_MOF_CV const
#include "funcref_impl.h"
#endif // __glibcxx_function_ref
#endif // move_only_function || copyable_function || function_ref
#endif // _GLIBCXX_FUNCWRAP_H