-
Notifications
You must be signed in to change notification settings - Fork 919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEA] Alternate design for owning/non-owning comparators #11040
Comments
Staring at this some more and thinking about names for the "owning" comparators I realized that there is effectively no reason for them to exist. Once you make the callables freestanding types, the only purpose of the owning comparators is to add the minor convenience of not needing to construct the preprocessed tables yourself. Otherwise we can eliminate them entirely.
I have an idea of how we can get rid of needing to be explicit about |
This is how I was thinking of designing this originally. |
I would prefer some other term like |
Alright, here's how we can get rid of the owning comparator types all together (obviously keeping the https://godbolt.org/z/fz1veocdc The main idea is to just infer "self" vs "two-table" based on how many tables are passed to the |
IMO, it looks more natural to do it this way:
than doing this way:
Maybe I missed some key insight here? |
Cuts both ways :)
Furthermore, the
Also, if you want to reuse the same preprocessed tables with a builder it becomes even more code:
All the "builder" does is hide the construction of the Also, with a "builder" it's not clear what it's lifetime requirements are. Is it owning? How long do I need to keep it alive? Constructing the |
This issue has been labeled |
This issue has been labeled |
One additional consideration that came up here during the implementation of the list lexicographic comparator is the need for separate code paths for when the compared tables contain nested data to avoid slowdowns of the non-nested data case due to the compiler's inability to sufficiently inline and optimize the complex code paths involving nested types. Whatever approach we take here will need to account for that as well. |
Is your feature request related to a problem? Please describe.
The new experimental row operators require non-trivial preprocessing that involves new allocations whose lifetime must be maintained while attempting to do any row-wise operations on the specified data.
To manage this, we introduced owning and non-owning comparator types.
For example,
self_comparator
is an owning type that handles doing row-wise operations on a single table.self_comparator
is not a binary callable object (it doesn't have anoperator()
). Creating the actual non-owning callable object is currently done through a member factory function of the owning type (renamed in #10870).After reviewing code using this functionality I've noticed that the callable being returned from a member of the owning type is a bit awkward. For instance the
s.less()
call above isn't immediately obvious that this is actually a factory returning a callable function object. One way to remedy that could be to call its.make_less()
instead, but I think there's an all together better way.Describe the solution you'd like
Inspired by
std::
function objects likestd::less/std::equal_to
, I think we should make the callable objects currently being returned from functions likeless()/less_equivalent()/equal_to()
to instead be freestanding types that are constructible from the owning types instead of being returned from a factory of the owning type.I think this would simplify the owning type as well as make the owner/viewer relationship more clear and explicit.
For example, the code above would become:
Here's a high level sketch of how this idea could be implemented: https://godbolt.org/z/5fbK7PTb6
Salient points:
less
is a standalone type constructible from theowning
typeless
is afriend
of the owning type to access internalsless
deletes constructions from an r-value ref of the owning type to prevent construction from a temporary of the owning type. If allowed, this would lead to dangling references.less::operator()
just invoke thePhysicalComparator
. The actual implementation would have more layers. It would be roughly equivalent to what the internals of theself_comparator::less
factory above does today.Additional Thoughts
I've come to believe that "comparator" is probably an inappropriate name for the owning types. It's not a comparator (not invokable), it just preprocesses and holds data needed by the actual comparators.
I don't have a good suggestion for a different name yet.
The text was updated successfully, but these errors were encountered: