`<future>`: Make `packaged_task` accept move-only functors
Fixes #321.
The issue was considered ABI-breaking, but I think it can be resolved in an ABI-preserving way like #2568. This PR adds internal constructors to function to accept non-copy-constructible functors and add static_assert to keep the copyability checking for standard constructors. Valid user codes won't be able to call these internal constructors.
Also implements the previously missing Mandates in [futures.task.members]/3, and switches to use move construction in reset per [futures.task.members]/26.
Notes:
- The internal constructors are made constrained templates to avoid affecting overload resolution unexpectedly, see LLVM-103409.
- The involved allocator-extended constructors were removed in C++17 by WG21-P0302R1 and LWG-2921, so this PR cites WG21-N4140 in the C++17-removed constructors.
- The fix should work for most move-only types. Although there can be classes whose copy constructor are only invalid in instantation. In vNext we should completely get rid of
function. - If the
function<R(Args...)>is a program-defined specialization, this approach doesn't work. I don't think any user should specializestd::function, but this is allowed by the standard. - Three
_Packaged_statespecializations are merged into one. I believe this can ease maintenance.
- In vNext we should completely get rid of
function.
I think it worth creating vNext issue.
move_only_function might be helpful for vNext implementation.
I think it worth creating vNext issue.
Or maybe TRANSITION, ABI comment(s)
- In vNext we should completely get rid of
function.I think it worth creating vNext issue.
We already have #321.
EDIT: ... which will probably be closed by this PR, because it's about move-only functors and not about removing the use of function. Sorry, I'm used to thinking of this as the "stop using function in packaged_task" issue.
- The involved allocator-extended constructors were removed in C++17 by WG21-P0302R1 and LWG-2921, so this PR cites WG21-N4140 in the C++17-removed constructors.
N.B. I'm proposing to restore packaged_task(allocator_arg_t, const Allocator&, F&&)
N.B. I'm proposing to restore
packaged_task(allocator_arg_t, const Allocator&, F&&)
See LWG3003.
And I've just created LWG4158 which is also about packaged_task.
Thanks @jwakely! BTW, in this repo's issues you can say LWG-4158 with a dash to use the autolink syntax we've set up - no need to manually craft hyperlinks. (https://github.com/microsoft/STL/wiki/Custom-Autolinks has the full list.)
Thanks for the extremely careful work! :heart_eyes_cat:
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.
I pushed a commit to perma-workaround VSO-2279389 "/clr C++20 can't handle struct MoveOnlyFunctor defined in a function template, emitting fatal error C1193: an error expected in yyaction.cpp(2899) not reached". Moving it out of the function template is sufficient and reasonable to do permanently.
Thanks for fixing this impossible bug! :lady_beetle: :white_check_mark: :heart_eyes_cat:
I think it worth creating vNext issue.
Or maybe
TRANSITION, ABIcomment(s)
#5009 is created for tracking.