This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Support const-qualified unique_functions
ClosedPublic

Authored by sammccall on Jun 25 2020, 10:29 AM.

Details

Summary

This technique should extend to rvalue-qualified etc, but I didn't add any.
I removed "volatile" from the future plans, which seems... speculative at best.

While here I moved the callbacks object out of the constructor into a
variable template, which I believe addresses the fixme there about unused
objects.

(I'm not a template guru, so it's always possible the old version was designed
for compile-time performance in a way I'm missing)

Diff Detail

Event Timeline

sammccall created this revision.Jun 25 2020, 10:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 25 2020, 10:29 AM
kadircet added inline comments.Jun 26 2020, 1:29 AM
llvm/include/llvm/ADT/FunctionExtras.h
131

nit: let's keep this and make use of it in getCallPtr instead of inlining.

162

nit: drop this (also the one before getNonTriivialCallbacks())?

173

nit: again drop this

190–191

nit: rename this to CalledAsT ?

213

s/to an/an/

216

move and destroy pointers don't really depend on CallableT maybe change this to only take CalledAsT ?

223

again this also doesn't depend on CallableT

226

maybe CalledAs ?

231

s/CallAsT/CalledAsT/

(or rename in the other way for the rest of the file)

359

call Base(nullptr_t), also in the mutable version?

361

drop this ?

371

drop this ?

llvm/unittests/ADT/FunctionExtrasTest.cpp
230

only-moveable captures are already tested elsewhere. is there a specific reason for this capture ?

sammccall marked 12 inline comments as done.Jun 26 2020, 3:17 AM
sammccall added inline comments.
llvm/include/llvm/ADT/FunctionExtras.h
216

I don't think using e.g. MoveAs<CalledAsT> will work: you almost always can't move from a const T.

You could do something like MoveAs<remove_cv_t<CalledAsT>> or have MoveAs const_cast. But that's just a different design, and I don't think particularly a better one: having both CallableT and CalledAsT explicitly specified (with the base class responsible for ensuring they're compatible) seems more robust than trying to make assumptions about how to calculate one from the other.

For example, when rvalue-ref qualified functions get added, I think it's nice not to have to worry about updating the metaprogramming to calculate the underlying type.

223

This is a specialization of the template above, so I don't think there's anything we can change here if the above stays the same.

359

This is "just" syntax sugar for the default constructor, and that's hardly obscure.

I think it's unneccesarily confusing to implement the public API in the base class where it doesn't save any complexity, so I've removed the nullptr_t from the base instead.

(I'm torn on operator bool as it's the last thing publicly exposed from the base, but I don't think it matters much)

361

it's required here to call a method from a dependent base.
(That's where all the other extra thises came from - code that I had in one of these subclasses and then moved)

llvm/unittests/ADT/FunctionExtrasTest.cpp
230

Have to make the machinery sweat a little!

More seriously, if the underlying functor is copyable, then MoveImpl<const lambda> *would* compile... but does a copy.

So there are reasonable-looking implementations where move works and const works but move const doesn't work. (but I admit I only worked this out after the fact).

sammccall updated this revision to Diff 273643.Jun 26 2020, 3:18 AM
sammccall marked 2 inline comments as done.

Address comments

kadircet accepted this revision.Jun 26 2020, 7:03 AM

Thanks for all the explanations, LGTM!

llvm/include/llvm/ADT/FunctionExtras.h
162

return isTrivialCallback() ? getTrivialCallback()->CallPtr : getNonTrivialCallbacks()->CallPtr;

This revision is now accepted and ready to land.Jun 26 2020, 7:03 AM
This revision was automatically updated to reflect the committed changes.
sammccall marked an inline comment as done.