From bcf1341a6002e5944d58258d3269d77438399a4d Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:24:03 +0200 Subject: [PATCH 1/9] _Move_only_function_base -> _Function_base --- stl/inc/functional | 44 +++++++++---------- .../move_only_function_specializations.py | 2 +- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 6c26acfb92c..0363eef2e74 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -973,7 +973,7 @@ private: #if _HAS_CXX23 template -class _Move_only_function_base; +class _Function_base; #endif // _HAS_CXX23 template @@ -1103,7 +1103,7 @@ protected: private: #if _HAS_CXX23 - friend _Move_only_function_base<_Ret, false, _Types...>; + friend _Function_base<_Ret, false, _Types...>; #endif // _HAS_CXX23 bool _Local() const noexcept { // test for locally stored copy of object @@ -1382,7 +1382,7 @@ _NODISCARD bool operator!=(nullptr_t, const function<_Fty>& _Other) noexcept { enum class _Function_storage_mode { _Small, _Large }; // _Move_only_function_data is defined as an array of pointers. -// The first element is always a pointer to _Move_only_function_base::_Impl_t; it emulates a vtable pointer. +// The first element is always a pointer to _Function_base::_Impl_t; it emulates a vtable pointer. // The other pointers are used as storage for a small functor; // if the functor does not fit in, the second pointer is the pointer to allocated storage, the rest are unused. union alignas(max_align_t) _Move_only_function_data { @@ -1423,7 +1423,7 @@ union alignas(max_align_t) _Move_only_function_data { // Treat a small function as if it has this size too if it fits and is trivially copyable. inline constexpr size_t _Minimum_function_size = 2 * sizeof(void*); -// The below functions are __stdcall as they are called by pointers from _Move_only_function_base::_Impl_t. +// The below functions are __stdcall as they are called by pointers from _Function_base::_Impl_t. // (We use explicit __stdcall to make the ABI stable for translation units with different calling convention options.) // Non-template functions are still defined inline, as the compiler may be able to devirtualize some calls. @@ -1573,7 +1573,7 @@ _NODISCARD void* _Function_new_large(_CTypes&&... _Args) { } template -class _Move_only_function_base { +class _Function_base { public: using result_type = _Rx; @@ -1608,9 +1608,9 @@ public: _Move_only_function_data _Data; - _Move_only_function_base() noexcept = default; // leaves fields uninitialized + _Function_base() noexcept = default; // leaves fields uninitialized - _Move_only_function_base(_Move_only_function_base&& _Other) noexcept { + _Function_base(_Function_base&& _Other) noexcept { _Checked_move(_Data, _Other._Data); _Other._Reset_to_null(); } @@ -1676,7 +1676,7 @@ public: } } - void _Move_assign(_Move_only_function_base&& _Other) noexcept { + void _Move_assign(_Function_base&& _Other) noexcept { // As specified in N4950 [func.wrap.move.ctor]/22, we are expected to first move the new target, // then finally destroy the old target. // It is more efficient to do the reverse - this way no temporary storage for the old target will be used. @@ -1711,7 +1711,7 @@ public: _Other._Reset_to_null(); } - void _Swap(_Move_only_function_base& _Other) noexcept { + void _Swap(_Function_base& _Other) noexcept { _Move_only_function_data _Tmp; _Checked_move(_Tmp, _Data); @@ -1826,7 +1826,7 @@ class _Move_only_function_call { // (Avoiding C++ preprocessor for better IDE navigation and debugging experience) template -class _Move_only_function_call<_Rx(_Types...)> : public _Move_only_function_base<_Rx, false, _Types...> { +class _Move_only_function_call<_Rx(_Types...)> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1841,7 +1841,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) &> : public _Move_only_function_base<_Rx, false, _Types...> { +class _Move_only_function_call<_Rx(_Types...) &> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1855,7 +1855,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) &&> : public _Move_only_function_base<_Rx, false, _Types...> { +class _Move_only_function_call<_Rx(_Types...) &&> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&&; @@ -1869,7 +1869,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const> : public _Move_only_function_base<_Rx, false, _Types...> { +class _Move_only_function_call<_Rx(_Types...) const> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1884,7 +1884,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const&> : public _Move_only_function_base<_Rx, false, _Types...> { +class _Move_only_function_call<_Rx(_Types...) const&> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1898,7 +1898,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const&&> : public _Move_only_function_base<_Rx, false, _Types...> { +class _Move_only_function_call<_Rx(_Types...) const&&> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&&; @@ -1913,7 +1913,7 @@ public: #ifdef __cpp_noexcept_function_type template -class _Move_only_function_call<_Rx(_Types...) noexcept> : public _Move_only_function_base<_Rx, true, _Types...> { +class _Move_only_function_call<_Rx(_Types...) noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1928,7 +1928,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) & noexcept> : public _Move_only_function_base<_Rx, true, _Types...> { +class _Move_only_function_call<_Rx(_Types...) & noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1942,7 +1942,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) && noexcept> : public _Move_only_function_base<_Rx, true, _Types...> { +class _Move_only_function_call<_Rx(_Types...) && noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&&; @@ -1956,7 +1956,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const noexcept> : public _Move_only_function_base<_Rx, true, _Types...> { +class _Move_only_function_call<_Rx(_Types...) const noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1971,8 +1971,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const & noexcept> - : public _Move_only_function_base<_Rx, true, _Types...> { +class _Move_only_function_call<_Rx(_Types...) const & noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1986,8 +1985,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const && noexcept> - : public _Move_only_function_base<_Rx, true, _Types...> { +class _Move_only_function_call<_Rx(_Types...) const && noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&&; diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index 548bf51486b..59c8bad45a4 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -6,7 +6,7 @@ def specialization(cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: return f"""template class _Move_only_function_call<_Rx(_Types...) {cv} {ref} {noex}> - : public _Move_only_function_base<_Rx, {noex_val}, _Types...> {{ + : public _Function_base<_Rx, {noex_val}, _Types...> {{ public: template using _VtInvQuals = {cv} _Vt {ref_inv}; From 15cc6fddc69f954968ccf000eac1f79d12233895 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:24:44 +0200 Subject: [PATCH 2/9] _Move_only_function_call -> _Function_call --- stl/inc/functional | 32 +++++++++---------- .../move_only_function_specializations.py | 4 +-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 0363eef2e74..3c7f41c0cee 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1407,7 +1407,7 @@ union alignas(max_align_t) _Move_only_function_data { _NODISCARD _Fn* _Fn_ptr() const noexcept { if constexpr (_Mode == _Function_storage_mode::_Small) { // cast away const to avoid complication of const propagation to here; - // const correctness is still enforced by _Move_only_function_call specializations. + // const correctness is still enforced by _Function_call specializations. return static_cast<_Fn*>(const_cast<_Move_only_function_data*>(this)->_Buf_ptr<_Fn>()); } else { return static_cast<_Fn*>(_Pointers[1]); @@ -1814,7 +1814,7 @@ public: }; template -class _Move_only_function_call { +class _Function_call { static_assert(_Always_false>, "std::move_only_function only accepts function types as template arguments, " "with possibly const/ref/noexcept qualifiers. Also, unlike std::function, " @@ -1826,7 +1826,7 @@ class _Move_only_function_call { // (Avoiding C++ preprocessor for better IDE navigation and debugging experience) template -class _Move_only_function_call<_Rx(_Types...)> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...)> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1841,7 +1841,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) &> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) &> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1855,7 +1855,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) &&> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) &&> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&&; @@ -1869,7 +1869,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) const> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1884,7 +1884,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const&> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) const&> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1898,7 +1898,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const&&> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) const&&> : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&&; @@ -1913,7 +1913,7 @@ public: #ifdef __cpp_noexcept_function_type template -class _Move_only_function_call<_Rx(_Types...) noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1928,7 +1928,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) & noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) & noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1942,7 +1942,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) && noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) && noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&&; @@ -1956,7 +1956,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) const noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1971,7 +1971,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const & noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) const & noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1985,7 +1985,7 @@ public: }; template -class _Move_only_function_call<_Rx(_Types...) const && noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) const && noexcept> : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&&; @@ -2000,9 +2000,9 @@ public: #endif // defined(__cpp_noexcept_function_type) _EXPORT_STD template -class move_only_function : private _Move_only_function_call<_Signature...> { +class move_only_function : private _Function_call<_Signature...> { private: - using _Call = _Move_only_function_call<_Signature...>; + using _Call = _Function_call<_Signature...>; template static constexpr bool _Enable_one_arg_constructor = !is_same_v, move_only_function> diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index 59c8bad45a4..959cdd81bbb 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -1,11 +1,11 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# This script generates the partial specializations of _Move_only_function_call in . +# This script generates the partial specializations of _Function_call in . def specialization(cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: return f"""template -class _Move_only_function_call<_Rx(_Types...) {cv} {ref} {noex}> +class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Function_base<_Rx, {noex_val}, _Types...> {{ public: template From 86c146f14f6721e8260ebd47d00a8686ae2eb2ba Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:29:26 +0200 Subject: [PATCH 3/9] _Move_only_function_data -> _Function_data --- stl/inc/functional | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 3c7f41c0cee..8b2e5d69a32 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1381,11 +1381,11 @@ _NODISCARD bool operator!=(nullptr_t, const function<_Fty>& _Other) noexcept { #if _HAS_CXX23 enum class _Function_storage_mode { _Small, _Large }; -// _Move_only_function_data is defined as an array of pointers. +// _Function_data is defined as an array of pointers. // The first element is always a pointer to _Function_base::_Impl_t; it emulates a vtable pointer. // The other pointers are used as storage for a small functor; // if the functor does not fit in, the second pointer is the pointer to allocated storage, the rest are unused. -union alignas(max_align_t) _Move_only_function_data { +union alignas(max_align_t) _Function_data { void* _Pointers[_Small_object_num_ptrs]; const void* _Impl; char _Data; // For aliasing @@ -1408,7 +1408,7 @@ union alignas(max_align_t) _Move_only_function_data { if constexpr (_Mode == _Function_storage_mode::_Small) { // cast away const to avoid complication of const propagation to here; // const correctness is still enforced by _Function_call specializations. - return static_cast<_Fn*>(const_cast<_Move_only_function_data*>(this)->_Buf_ptr<_Fn>()); + return static_cast<_Fn*>(const_cast<_Function_data*>(this)->_Buf_ptr<_Fn>()); } else { return static_cast<_Fn*>(_Pointers[1]); } @@ -1428,18 +1428,18 @@ inline constexpr size_t _Minimum_function_size = 2 * sizeof(void*); // Non-template functions are still defined inline, as the compiler may be able to devirtualize some calls. template -[[noreturn]] _Rx __stdcall _Function_not_callable(const _Move_only_function_data&, _Types&&...) noexcept { +[[noreturn]] _Rx __stdcall _Function_not_callable(const _Function_data&, _Types&&...) noexcept { _STL_REPORT_ERROR("empty move_only_function call (N5008 [func.wrap.move.inv]/2)"); _STL_UNREACHABLE; // no return value available for "continue on error" } template -[[noreturn]] _Rx __stdcall _Function_old_not_callable(const _Move_only_function_data&, _Types&&...) { +[[noreturn]] _Rx __stdcall _Function_old_not_callable(const _Function_data&, _Types&&...) { _Xbad_function_call(); } template -_NODISCARD _Rx __stdcall _Function_inv(const _Move_only_function_data& _Self, _Types&&... _Args) noexcept(_Noex) { +_NODISCARD _Rx __stdcall _Function_inv(const _Function_data& _Self, _Types&&... _Args) noexcept(_Noex) { if constexpr (is_void_v<_Rx>) { (void) _STD invoke(static_cast<_VtInvQuals>(*_Self._Fn_ptr<_Vt, _Mode>()), _STD forward<_Types>(_Args)...); } else { @@ -1448,12 +1448,12 @@ _NODISCARD _Rx __stdcall _Function_inv(const _Move_only_function_data& _Self, _T } template -_NODISCARD _Rx __stdcall _Function_inv_old(const _Move_only_function_data& _Self, _Types&&... _Args) { +_NODISCARD _Rx __stdcall _Function_inv_old(const _Function_data& _Self, _Types&&... _Args) { return _Self._Fn_ptr<_Fn, _Mode>()->_Do_call(_STD forward<_Types>(_Args)...); } template -void __stdcall _Function_move_small(_Move_only_function_data& _Self, _Move_only_function_data& _Src) noexcept { +void __stdcall _Function_move_small(_Function_data& _Self, _Function_data& _Src) noexcept { const auto _Src_fn_ptr = _Src._Fn_ptr<_Vt, _Function_storage_mode::_Small>(); ::new (_Self._Buf_ptr<_Vt>()) _Vt(_STD move(*_Src_fn_ptr)); _Src_fn_ptr->~_Vt(); @@ -1461,17 +1461,17 @@ void __stdcall _Function_move_small(_Move_only_function_data& _Self, _Move_only_ } template -void __stdcall _Function_move_memcpy(_Move_only_function_data& _Self, _Move_only_function_data& _Src) noexcept { +void __stdcall _Function_move_memcpy(_Function_data& _Self, _Function_data& _Src) noexcept { _CSTD memcpy(&_Self._Data, &_Src._Data, _Size); // Copy Impl* and functor data } -inline void __stdcall _Function_move_large(_Move_only_function_data& _Self, _Move_only_function_data& _Src) noexcept { +inline void __stdcall _Function_move_large(_Function_data& _Self, _Function_data& _Src) noexcept { _CSTD memcpy(&_Self._Data, &_Src._Data, _Minimum_function_size); // Copy Impl* and functor data } #ifdef _WIN64 template -void __stdcall _Function_move_old_small(_Move_only_function_data& _Self, _Move_only_function_data& _Src) noexcept { +void __stdcall _Function_move_old_small(_Function_data& _Self, _Function_data& _Src) noexcept { _Fn* const _Old_fn_impl = _Src._Fn_ptr<_Fn, _Function_storage_mode::_Small>(); _Old_fn_impl->_Move(_Self._Buf_ptr()); _Old_fn_impl->_Delete_this(false); @@ -1480,27 +1480,27 @@ void __stdcall _Function_move_old_small(_Move_only_function_data& _Self, _Move_o #endif // ^^^ 64-bit ^^^ template -void __stdcall _Function_destroy_small(_Move_only_function_data& _Self) noexcept { +void __stdcall _Function_destroy_small(_Function_data& _Self) noexcept { _Self._Fn_ptr<_Vt, _Function_storage_mode::_Small>()->~_Vt(); } -inline void __stdcall _Function_deallocate_large_default_aligned(_Move_only_function_data& _Self) noexcept { +inline void __stdcall _Function_deallocate_large_default_aligned(_Function_data& _Self) noexcept { ::operator delete(_Self._Fn_ptr()); } template -void __stdcall _Function_destroy_old_large(_Move_only_function_data& _Self) noexcept { +void __stdcall _Function_destroy_old_large(_Function_data& _Self) noexcept { _Self._Fn_ptr<_Fn, _Function_storage_mode::_Large>()->_Delete_this(true); } #ifdef _WIN64 template -void __stdcall _Function_destroy_old_small(_Move_only_function_data& _Self) noexcept { +void __stdcall _Function_destroy_old_small(_Function_data& _Self) noexcept { _Self._Fn_ptr<_Fn, _Function_storage_mode::_Small>()->_Delete_this(false); } #else // ^^^ 64-bit / 32-bit vvv template -void __stdcall _Function_destroy_old_small_as_large(_Move_only_function_data& _Self) noexcept { +void __stdcall _Function_destroy_old_small_as_large(_Function_data& _Self) noexcept { _Fn* const _Old_fn_impl = _Self._Fn_ptr<_Fn, _Function_storage_mode::_Large>(); _Old_fn_impl->_Delete_this(false); ::operator delete(static_cast(_Old_fn_impl)); @@ -1508,7 +1508,7 @@ void __stdcall _Function_destroy_old_small_as_large(_Move_only_function_data& _S #endif // ^^^ 32-bit ^^^ template -void __stdcall _Function_deallocate_large_overaligned(_Move_only_function_data& _Self) noexcept { +void __stdcall _Function_deallocate_large_overaligned(_Function_data& _Self) noexcept { _STL_INTERNAL_STATIC_ASSERT(_Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__); #ifdef __cpp_aligned_new ::operator delete(_Self._Fn_ptr(), align_val_t{_Align}); @@ -1518,7 +1518,7 @@ void __stdcall _Function_deallocate_large_overaligned(_Move_only_function_data& } template -void __stdcall _Function_destroy_large(_Move_only_function_data& _Self) noexcept { +void __stdcall _Function_destroy_large(_Function_data& _Self) noexcept { const auto _Pfn = _Self._Fn_ptr<_Vt, _Function_storage_mode::_Large>(); _Pfn->~_Vt(); #ifdef __cpp_aligned_new @@ -1533,7 +1533,7 @@ void __stdcall _Function_destroy_large(_Move_only_function_data& _Self) noexcept template constexpr size_t _Function_small_copy_size = // We copy Impl* and the functor data at once - _Move_only_function_data::_Buf_offset<_Vt> // Impl* plus possible alignment + _Function_data::_Buf_offset<_Vt> // Impl* plus possible alignment + (size_t{sizeof(_Vt) + sizeof(void*) - 1} & ~size_t{sizeof(void*) - 1}); // size in whole pointers template @@ -1586,13 +1586,13 @@ public: // empty function from a DLL that is unloaded later, and then safely moving/destroying that empty function. // Calls target - _Rx(__stdcall* _Invoke)(const _Move_only_function_data&, _Types&&...) _NOEXCEPT_FNPTR_COND(_Noexcept); + _Rx(__stdcall* _Invoke)(const _Function_data&, _Types&&...) _NOEXCEPT_FNPTR_COND(_Noexcept); // Moves the data, including pointer to "vtable", AND destroys old data (not resetting its "vtable"). // nullptr if we can trivially move two pointers. - void(__stdcall* _Move)(_Move_only_function_data&, _Move_only_function_data&) _NOEXCEPT_FNPTR; + void(__stdcall* _Move)(_Function_data&, _Function_data&) _NOEXCEPT_FNPTR; // Destroys data (not resetting its "vtable"). // nullptr if destruction is a no-op. - void(__stdcall* _Destroy)(_Move_only_function_data&) _NOEXCEPT_FNPTR; + void(__stdcall* _Destroy)(_Function_data&) _NOEXCEPT_FNPTR; }; enum class _Impl_kind { @@ -1606,7 +1606,7 @@ public: #endif // ^^^ 32-bit ^^^ }; - _Move_only_function_data _Data; + _Function_data _Data; _Function_base() noexcept = default; // leaves fields uninitialized @@ -1660,14 +1660,14 @@ public: } } - static void _Checked_destroy(_Move_only_function_data& _Data) noexcept { + static void _Checked_destroy(_Function_data& _Data) noexcept { const auto _Impl = _Get_impl(_Data); if (_Impl->_Destroy) { _Impl->_Destroy(_Data); } } - static void _Checked_move(_Move_only_function_data& _Data, _Move_only_function_data& _Src) noexcept { + static void _Checked_move(_Function_data& _Data, _Function_data& _Src) noexcept { const auto _Impl = _Get_impl(_Src); if (_Impl->_Move) { _Impl->_Move(_Data, _Src); @@ -1697,7 +1697,7 @@ public: _Other_impl_move(_Data, _Other._Data); } else { // General case involving a temporary - _Move_only_function_data _Tmp; + _Function_data _Tmp; if (_This_impl->_Move) { _This_impl->_Move(_Tmp, _Data); @@ -1712,7 +1712,7 @@ public: } void _Swap(_Function_base& _Other) noexcept { - _Move_only_function_data _Tmp; + _Function_data _Tmp; _Checked_move(_Tmp, _Data); _Checked_move(_Data, _Other._Data); @@ -1725,14 +1725,14 @@ public: template static constexpr bool _Large_function_engaged = alignof(_Vt) > alignof(max_align_t) - || sizeof(_Vt) > _Move_only_function_data::_Buf_size<_Vt> + || sizeof(_Vt) > _Function_data::_Buf_size<_Vt> || !is_nothrow_move_constructible_v<_Vt>; _NODISCARD auto _Get_invoke() const noexcept { return _Get_impl(_Data)->_Invoke; } - _NODISCARD static const _Impl_t* _Get_impl(const _Move_only_function_data& _Data) noexcept { + _NODISCARD static const _Impl_t* _Get_impl(const _Function_data& _Data) noexcept { static constexpr _Impl_t _Null_move_only_function = { _Function_not_callable<_Rx, _Types...>, nullptr, From 7c4639fa765db3a80b3047fab4c4e68b83766bb7 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:33:36 +0200 Subject: [PATCH 4/9] These are no longer wrapped Does not match clang-format exactly, but still closer --- tools/scripts/move_only_function_specializations.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index 959cdd81bbb..c721b057fc5 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -5,8 +5,7 @@ def specialization(cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: return f"""template -class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> - : public _Function_base<_Rx, {noex_val}, _Types...> {{ +class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Function_base<_Rx, {noex_val}, _Types...> {{ public: template using _VtInvQuals = {cv} _Vt {ref_inv}; From 7984a800773dd79a0dd59ac0af564cdfb50b3d93 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:34:46 +0200 Subject: [PATCH 5/9] terminology --- stl/inc/functional | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/functional b/stl/inc/functional index 8b2e5d69a32..62e05471e63 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1608,7 +1608,7 @@ public: _Function_data _Data; - _Function_base() noexcept = default; // leaves fields uninitialized + _Function_base() noexcept = default; // leaves the data member uninitialized _Function_base(_Function_base&& _Other) noexcept { _Checked_move(_Data, _Other._Data); From fa55730e6ef508acf37d7c7c2043ebdd71df8b91 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:47:00 +0200 Subject: [PATCH 6/9] voidify --- stl/inc/functional | 42 ++++++++++--------- .../move_only_function_specializations.py | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 62e05471e63..441008a5949 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1428,28 +1428,30 @@ inline constexpr size_t _Minimum_function_size = 2 * sizeof(void*); // Non-template functions are still defined inline, as the compiler may be able to devirtualize some calls. template -[[noreturn]] _Rx __stdcall _Function_not_callable(const _Function_data&, _Types&&...) noexcept { +[[noreturn]] _Rx __stdcall _Function_not_callable(const void*, _Types&&...) noexcept { _STL_REPORT_ERROR("empty move_only_function call (N5008 [func.wrap.move.inv]/2)"); _STL_UNREACHABLE; // no return value available for "continue on error" } template -[[noreturn]] _Rx __stdcall _Function_old_not_callable(const _Function_data&, _Types&&...) { +[[noreturn]] _Rx __stdcall _Function_old_not_callable(const void*, _Types&&...) { _Xbad_function_call(); } template -_NODISCARD _Rx __stdcall _Function_inv(const _Function_data& _Self, _Types&&... _Args) noexcept(_Noex) { +_NODISCARD _Rx __stdcall _Function_inv(const void* _Self, _Types&&... _Args) noexcept(_Noex) { + const auto _Ptr = static_cast(_Self)->_Fn_ptr<_Vt, _Mode>(); if constexpr (is_void_v<_Rx>) { - (void) _STD invoke(static_cast<_VtInvQuals>(*_Self._Fn_ptr<_Vt, _Mode>()), _STD forward<_Types>(_Args)...); + (void) _STD invoke(static_cast<_VtInvQuals>(*_Ptr), _STD forward<_Types>(_Args)...); } else { - return _STD invoke(static_cast<_VtInvQuals>(*_Self._Fn_ptr<_Vt, _Mode>()), _STD forward<_Types>(_Args)...); + return _STD invoke(static_cast<_VtInvQuals>(*_Ptr), _STD forward<_Types>(_Args)...); } } template -_NODISCARD _Rx __stdcall _Function_inv_old(const _Function_data& _Self, _Types&&... _Args) { - return _Self._Fn_ptr<_Fn, _Mode>()->_Do_call(_STD forward<_Types>(_Args)...); +_NODISCARD _Rx __stdcall _Function_inv_old(const void* _Self, _Types&&... _Args) { + const auto _Ptr = static_cast(_Self)->_Fn_ptr<_Fn, _Mode>(); + return _Ptr->_Do_call(_STD forward<_Types>(_Args)...); } template @@ -1586,7 +1588,7 @@ public: // empty function from a DLL that is unloaded later, and then safely moving/destroying that empty function. // Calls target - _Rx(__stdcall* _Invoke)(const _Function_data&, _Types&&...) _NOEXCEPT_FNPTR_COND(_Noexcept); + _Rx(__stdcall* _Invoke)(const void*, _Types&&...) _NOEXCEPT_FNPTR_COND(_Noexcept); // Moves the data, including pointer to "vtable", AND destroys old data (not resetting its "vtable"). // nullptr if we can trivially move two pointers. void(__stdcall* _Move)(_Function_data&, _Function_data&) _NOEXCEPT_FNPTR; @@ -1836,7 +1838,7 @@ public: is_invocable_r_v<_Rx, _Vt, _Types...> && is_invocable_r_v<_Rx, _Vt&, _Types...>; _Rx operator()(_Types... _Args) { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1850,7 +1852,7 @@ public: static constexpr bool _Is_callable_from = is_invocable_r_v<_Rx, _Vt&, _Types...>; _Rx operator()(_Types... _Args) & { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1864,7 +1866,7 @@ public: static constexpr bool _Is_callable_from = is_invocable_r_v<_Rx, _Vt, _Types...>; _Rx operator()(_Types... _Args) && { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1879,7 +1881,7 @@ public: is_invocable_r_v<_Rx, const _Vt, _Types...> && is_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1893,7 +1895,7 @@ public: static constexpr bool _Is_callable_from = is_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const& { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1907,7 +1909,7 @@ public: static constexpr bool _Is_callable_from = is_invocable_r_v<_Rx, const _Vt, _Types...>; _Rx operator()(_Types... _Args) const&& { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1923,7 +1925,7 @@ public: is_nothrow_invocable_r_v<_Rx, _Vt, _Types...> && is_nothrow_invocable_r_v<_Rx, _Vt&, _Types...>; _Rx operator()(_Types... _Args) noexcept { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1937,7 +1939,7 @@ public: static constexpr bool _Is_callable_from = is_nothrow_invocable_r_v<_Rx, _Vt&, _Types...>; _Rx operator()(_Types... _Args) & noexcept { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1951,7 +1953,7 @@ public: static constexpr bool _Is_callable_from = is_nothrow_invocable_r_v<_Rx, _Vt, _Types...>; _Rx operator()(_Types... _Args) && noexcept { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1966,7 +1968,7 @@ public: is_nothrow_invocable_r_v<_Rx, const _Vt, _Types...> && is_nothrow_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const noexcept { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1980,7 +1982,7 @@ public: static constexpr bool _Is_callable_from = is_nothrow_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const& noexcept { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; @@ -1994,7 +1996,7 @@ public: static constexpr bool _Is_callable_from = is_nothrow_invocable_r_v<_Rx, const _Vt, _Types...>; _Rx operator()(_Types... _Args) const&& noexcept { - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); } }; #endif // defined(__cpp_noexcept_function_type) diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index c721b057fc5..9ffa32b5174 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -14,7 +14,7 @@ class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Function_base<_ static constexpr bool _Is_callable_from = {callable}; _Rx operator()(_Types... _Args) {cv} {ref} {noex} {{ - return this->_Get_invoke()(this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); }} }}; """ From 6930883b1b75df00a0a1283745cd6bbce1e8b4af Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 12 Nov 2025 21:59:50 +0200 Subject: [PATCH 7/9] unconst --- stl/inc/functional | 32 +++++++++---------- .../move_only_function_specializations.py | 16 +++++----- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 441008a5949..6113d397541 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1404,11 +1404,9 @@ union alignas(max_align_t) _Function_data { } template - _NODISCARD _Fn* _Fn_ptr() const noexcept { + _NODISCARD _Fn* _Fn_ptr() noexcept { if constexpr (_Mode == _Function_storage_mode::_Small) { - // cast away const to avoid complication of const propagation to here; - // const correctness is still enforced by _Function_call specializations. - return static_cast<_Fn*>(const_cast<_Function_data*>(this)->_Buf_ptr<_Fn>()); + return static_cast<_Fn*>(_Buf_ptr<_Fn>()); } else { return static_cast<_Fn*>(_Pointers[1]); } @@ -1428,19 +1426,19 @@ inline constexpr size_t _Minimum_function_size = 2 * sizeof(void*); // Non-template functions are still defined inline, as the compiler may be able to devirtualize some calls. template -[[noreturn]] _Rx __stdcall _Function_not_callable(const void*, _Types&&...) noexcept { +[[noreturn]] _Rx __stdcall _Function_not_callable(void*, _Types&&...) noexcept { _STL_REPORT_ERROR("empty move_only_function call (N5008 [func.wrap.move.inv]/2)"); _STL_UNREACHABLE; // no return value available for "continue on error" } template -[[noreturn]] _Rx __stdcall _Function_old_not_callable(const void*, _Types&&...) { +[[noreturn]] _Rx __stdcall _Function_old_not_callable(void*, _Types&&...) { _Xbad_function_call(); } template -_NODISCARD _Rx __stdcall _Function_inv(const void* _Self, _Types&&... _Args) noexcept(_Noex) { - const auto _Ptr = static_cast(_Self)->_Fn_ptr<_Vt, _Mode>(); +_NODISCARD _Rx __stdcall _Function_inv(void* _Self, _Types&&... _Args) noexcept(_Noex) { + const auto _Ptr = static_cast<_Function_data*>(_Self)->_Fn_ptr<_Vt, _Mode>(); if constexpr (is_void_v<_Rx>) { (void) _STD invoke(static_cast<_VtInvQuals>(*_Ptr), _STD forward<_Types>(_Args)...); } else { @@ -1449,8 +1447,8 @@ _NODISCARD _Rx __stdcall _Function_inv(const void* _Self, _Types&&... _Args) noe } template -_NODISCARD _Rx __stdcall _Function_inv_old(const void* _Self, _Types&&... _Args) { - const auto _Ptr = static_cast(_Self)->_Fn_ptr<_Fn, _Mode>(); +_NODISCARD _Rx __stdcall _Function_inv_old(void* _Self, _Types&&... _Args) { + const auto _Ptr = static_cast<_Function_data*>(_Self)->_Fn_ptr<_Fn, _Mode>(); return _Ptr->_Do_call(_STD forward<_Types>(_Args)...); } @@ -1588,7 +1586,7 @@ public: // empty function from a DLL that is unloaded later, and then safely moving/destroying that empty function. // Calls target - _Rx(__stdcall* _Invoke)(const void*, _Types&&...) _NOEXCEPT_FNPTR_COND(_Noexcept); + _Rx(__stdcall* _Invoke)(void*, _Types&&...) _NOEXCEPT_FNPTR_COND(_Noexcept); // Moves the data, including pointer to "vtable", AND destroys old data (not resetting its "vtable"). // nullptr if we can trivially move two pointers. void(__stdcall* _Move)(_Function_data&, _Function_data&) _NOEXCEPT_FNPTR; @@ -1881,7 +1879,7 @@ public: is_invocable_r_v<_Rx, const _Vt, _Types...> && is_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const { - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(const_cast<_Function_data*>(&this->_Data), _STD forward<_Types>(_Args)...); } }; @@ -1895,7 +1893,7 @@ public: static constexpr bool _Is_callable_from = is_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const& { - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(const_cast<_Function_data*>(&this->_Data), _STD forward<_Types>(_Args)...); } }; @@ -1909,7 +1907,7 @@ public: static constexpr bool _Is_callable_from = is_invocable_r_v<_Rx, const _Vt, _Types...>; _Rx operator()(_Types... _Args) const&& { - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(const_cast<_Function_data*>(&this->_Data), _STD forward<_Types>(_Args)...); } }; @@ -1968,7 +1966,7 @@ public: is_nothrow_invocable_r_v<_Rx, const _Vt, _Types...> && is_nothrow_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const noexcept { - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(const_cast<_Function_data*>(&this->_Data), _STD forward<_Types>(_Args)...); } }; @@ -1982,7 +1980,7 @@ public: static constexpr bool _Is_callable_from = is_nothrow_invocable_r_v<_Rx, const _Vt&, _Types...>; _Rx operator()(_Types... _Args) const& noexcept { - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(const_cast<_Function_data*>(&this->_Data), _STD forward<_Types>(_Args)...); } }; @@ -1996,7 +1994,7 @@ public: static constexpr bool _Is_callable_from = is_nothrow_invocable_r_v<_Rx, const _Vt, _Types...>; _Rx operator()(_Types... _Args) const&& noexcept { - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()(const_cast<_Function_data*>(&this->_Data), _STD forward<_Types>(_Args)...); } }; #endif // defined(__cpp_noexcept_function_type) diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index 9ffa32b5174..51f28b4c7d7 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -3,7 +3,7 @@ # This script generates the partial specializations of _Function_call in . -def specialization(cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: +def specialization(self: str, cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: return f"""template class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Function_base<_Rx, {noex_val}, _Types...> {{ public: @@ -14,22 +14,22 @@ class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Function_base<_ static constexpr bool _Is_callable_from = {callable}; _Rx operator()(_Types... _Args) {cv} {ref} {noex} {{ - return this->_Get_invoke()(&this->_Data, _STD forward<_Types>(_Args)...); + return this->_Get_invoke()({self}, _STD forward<_Types>(_Args)...); }} }}; """ -def ref_permutations(cv: str, noex: str, noex_val: str, trait: str) -> str: - return specialization(cv, "", "&", noex, noex_val, \ +def ref_permutations(self: str, cv: str, noex: str, noex_val: str, trait: str) -> str: + return specialization(self, cv, "", "&", noex, noex_val, \ f"{trait}<_Rx, {cv} _Vt, _Types...> && {trait}<_Rx, {cv} _Vt&, _Types...>") + "\n" \ - + specialization(cv, "&", "&", noex, noex_val, f"{trait}<_Rx, {cv} _Vt&, _Types...>") + "\n" \ - + specialization(cv, "&&", "&&", noex, noex_val, f"{trait}<_Rx, {cv} _Vt, _Types...>") + + specialization(self, cv, "&", "&", noex, noex_val, f"{trait}<_Rx, {cv} _Vt&, _Types...>") + "\n" \ + + specialization(self, cv, "&&", "&&", noex, noex_val, f"{trait}<_Rx, {cv} _Vt, _Types...>") def cvref_permutations(noex: str, noex_val: str, trait: str) -> str: - return ref_permutations("", noex, noex_val, trait) + "\n" \ - + ref_permutations("const", noex, noex_val, trait) + return ref_permutations("&this->_Data", "", noex, noex_val, trait) + "\n" \ + + ref_permutations("const_cast<_Function_data*>(&this->_Data)", "const", noex, noex_val, trait) if __name__ == "__main__": From d734fb771d021fefeb2a22414e472122ab6bb0d8 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 18 Nov 2025 15:34:31 -0800 Subject: [PATCH 8/9] Add comments for generated code. --- stl/inc/functional | 38 +++++++++++++------ .../move_only_function_specializations.py | 3 +- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 6113d397541..92cef82ea9a 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1825,8 +1825,10 @@ class _Function_call { // /tools/scripts/move_only_function_specializations.py // (Avoiding C++ preprocessor for better IDE navigation and debugging experience) +// Beginning of generated code - DO NOT EDIT manually! template -class _Function_call<_Rx(_Types...)> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...)> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1841,7 +1843,8 @@ public: }; template -class _Function_call<_Rx(_Types...) &> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) &> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1855,7 +1858,8 @@ public: }; template -class _Function_call<_Rx(_Types...) &&> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) &&> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = _Vt&&; @@ -1869,7 +1873,8 @@ public: }; template -class _Function_call<_Rx(_Types...) const> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) const> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1884,7 +1889,8 @@ public: }; template -class _Function_call<_Rx(_Types...) const&> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) const&> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1898,7 +1904,8 @@ public: }; template -class _Function_call<_Rx(_Types...) const&&> : public _Function_base<_Rx, false, _Types...> { +class _Function_call<_Rx(_Types...) const&&> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, false, _Types...> { public: template using _VtInvQuals = const _Vt&&; @@ -1913,7 +1920,8 @@ public: #ifdef __cpp_noexcept_function_type template -class _Function_call<_Rx(_Types...) noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) noexcept> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1928,7 +1936,8 @@ public: }; template -class _Function_call<_Rx(_Types...) & noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) & noexcept> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&; @@ -1942,7 +1951,8 @@ public: }; template -class _Function_call<_Rx(_Types...) && noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) && noexcept> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = _Vt&&; @@ -1956,7 +1966,8 @@ public: }; template -class _Function_call<_Rx(_Types...) const noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) const noexcept> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1971,7 +1982,8 @@ public: }; template -class _Function_call<_Rx(_Types...) const & noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) const & noexcept> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&; @@ -1985,7 +1997,8 @@ public: }; template -class _Function_call<_Rx(_Types...) const && noexcept> : public _Function_base<_Rx, true, _Types...> { +class _Function_call<_Rx(_Types...) const && noexcept> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, true, _Types...> { public: template using _VtInvQuals = const _Vt&&; @@ -1998,6 +2011,7 @@ public: } }; #endif // defined(__cpp_noexcept_function_type) +// End of generated code - DO NOT EDIT manually! _EXPORT_STD template class move_only_function : private _Function_call<_Signature...> { diff --git a/tools/scripts/move_only_function_specializations.py b/tools/scripts/move_only_function_specializations.py index 51f28b4c7d7..ad49c62e49c 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -5,7 +5,8 @@ def specialization(self: str, cv: str, ref: str, ref_inv: str, noex: str, noex_val: str, callable: str) -> str: return f"""template -class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> : public _Function_base<_Rx, {noex_val}, _Types...> {{ +class _Function_call<_Rx(_Types...) {cv} {ref} {noex}> // Generated code - DO NOT EDIT manually! + : public _Function_base<_Rx, {noex_val}, _Types...> {{ public: template using _VtInvQuals = {cv} _Vt {ref_inv}; From d3cf01e7807930dd00396ad4cac399383c31b11f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 18 Nov 2025 15:50:52 -0800 Subject: [PATCH 9/9] Add top-level const to `_Self`. --- stl/inc/functional | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index 92cef82ea9a..65ad553b2da 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1437,7 +1437,7 @@ template } template -_NODISCARD _Rx __stdcall _Function_inv(void* _Self, _Types&&... _Args) noexcept(_Noex) { +_NODISCARD _Rx __stdcall _Function_inv(void* const _Self, _Types&&... _Args) noexcept(_Noex) { const auto _Ptr = static_cast<_Function_data*>(_Self)->_Fn_ptr<_Vt, _Mode>(); if constexpr (is_void_v<_Rx>) { (void) _STD invoke(static_cast<_VtInvQuals>(*_Ptr), _STD forward<_Types>(_Args)...); @@ -1447,7 +1447,7 @@ _NODISCARD _Rx __stdcall _Function_inv(void* _Self, _Types&&... _Args) noexcept( } template -_NODISCARD _Rx __stdcall _Function_inv_old(void* _Self, _Types&&... _Args) { +_NODISCARD _Rx __stdcall _Function_inv_old(void* const _Self, _Types&&... _Args) { const auto _Ptr = static_cast<_Function_data*>(_Self)->_Fn_ptr<_Fn, _Mode>(); return _Ptr->_Do_call(_STD forward<_Types>(_Args)...); }