diff --git a/stl/inc/functional b/stl/inc/functional index 6c26acfb92c..65ad553b2da 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 @@ -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. -// The first element is always a pointer to _Move_only_function_base::_Impl_t; it emulates a vtable pointer. +// _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 @@ -1404,11 +1404,9 @@ union alignas(max_align_t) _Move_only_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 _Move_only_function_call specializations. - return static_cast<_Fn*>(const_cast<_Move_only_function_data*>(this)->_Buf_ptr<_Fn>()); + return static_cast<_Fn*>(_Buf_ptr<_Fn>()); } else { return static_cast<_Fn*>(_Pointers[1]); } @@ -1423,37 +1421,39 @@ 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. template -[[noreturn]] _Rx __stdcall _Function_not_callable(const _Move_only_function_data&, _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 _Move_only_function_data&, _Types&&...) { +[[noreturn]] _Rx __stdcall _Function_old_not_callable(void*, _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(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>(*_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 _Move_only_function_data& _Self, _Types&&... _Args) { - return _Self._Fn_ptr<_Fn, _Mode>()->_Do_call(_STD forward<_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)...); } 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 @@ -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; @@ -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)(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)(_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,11 +1606,11 @@ public: #endif // ^^^ 32-bit ^^^ }; - _Move_only_function_data _Data; + _Function_data _Data; - _Move_only_function_base() noexcept = default; // leaves fields uninitialized + _Function_base() noexcept = default; // leaves the data member 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(); } @@ -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); @@ -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. @@ -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); @@ -1711,8 +1711,8 @@ public: _Other._Reset_to_null(); } - void _Swap(_Move_only_function_base& _Other) noexcept { - _Move_only_function_data _Tmp; + void _Swap(_Function_base& _Other) noexcept { + _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, @@ -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, " @@ -1825,8 +1825,10 @@ class _Move_only_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 _Move_only_function_call<_Rx(_Types...)> : public _Move_only_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&; @@ -1836,12 +1838,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) &> : public _Move_only_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&; @@ -1850,12 +1853,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) &&> : public _Move_only_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&&; @@ -1864,12 +1868,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) const> : public _Move_only_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&; @@ -1879,12 +1884,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) const&> : public _Move_only_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&; @@ -1893,12 +1899,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) const&&> : public _Move_only_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&&; @@ -1907,13 +1914,14 @@ 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)...); } }; #ifdef __cpp_noexcept_function_type template -class _Move_only_function_call<_Rx(_Types...) noexcept> : public _Move_only_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&; @@ -1923,12 +1931,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) & noexcept> : public _Move_only_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&; @@ -1937,12 +1946,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) && noexcept> : public _Move_only_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&&; @@ -1951,12 +1961,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) const noexcept> : public _Move_only_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&; @@ -1966,13 +1977,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) const & noexcept> - : public _Move_only_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&; @@ -1981,13 +1992,13 @@ 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)...); } }; template -class _Move_only_function_call<_Rx(_Types...) const && noexcept> - : public _Move_only_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&&; @@ -1996,15 +2007,16 @@ 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) +// End of generated code - DO NOT EDIT manually! _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 548bf51486b..ad49c62e49c 100644 --- a/tools/scripts/move_only_function_specializations.py +++ b/tools/scripts/move_only_function_specializations.py @@ -1,12 +1,12 @@ # 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: +def specialization(self: str, 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...> {{ +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}; @@ -15,22 +15,22 @@ class _Move_only_function_call<_Rx(_Types...) {cv} {ref} {noex}> 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__":