This is an archive of the discontinued LLVM Phabricator instance.

DepthFirstIterator.h: Use C++11 features to call a completed method onthe set type, instead of requiring that one exists.
AcceptedPublic

Authored by dberlin on Oct 11 2017, 9:42 AM.

Details

Summary

This makes the required set type of df_iterator a normal set again.
Previously, you had to have a set type with the completed method,
which meant not being able to reuse exist set types.

I'm a bit unhappy about the overload hack required to do this, so
adding some reviewers to see if they know a better way.

(PostOrderIterator.h has a similar requirement that i'll fix as a
followup, but it requires more work).

Completion is also really a function that belongs as part of the
iterator, but it was non-trivial to simply make the iterator take it
as a function without a lot of other changes (due to the need for a
default argument, etc), due to the fun of trying to use lambdas as
template parameters.

Event Timeline

dberlin created this revision.Oct 11 2017, 9:42 AM
dblaikie retitled this revision from DepthFirstIterator.h: Use C++11 features to call a completed method on the set type, instead of requiring that one exists. to DepthFirstIterator.h: Use C++11 features to call a completed method onthe set type, instead of requiring that one exists..Oct 16 2017, 7:03 PM
dblaikie added a subscriber: dblaikie.

I haven't heard any better approaches yet, but i'll give a week before committing this.

davide accepted this revision.Oct 19 2017, 11:01 AM

I personally don't know a better way, so I'm fine with this.

This revision is now accepted and ready to land.Oct 19 2017, 11:01 AM

BTW, are there other iterators where we want to apply this trick?

dblaikie added inline comments.Oct 20 2017, 10:05 AM
include/llvm/ADT/DepthFirstIterator.h
83

I'm guessing this is for consistency? But I'd probably write this with a traditional return type?

void call_completed_method_imp(...) {
88–89

What's the delayed return type achieve here - given that there's the fallback overload of call_completed_method_imp, it wouldn't be providing any SFINAE, would it? (& there's not some other overload of call_completed_method that'd be selected)

Should this be:

void call_completed_method(...) {
  return call_completed_method_imp(t, V, 0);
}
dberlin marked 2 inline comments as done.Oct 20 2017, 11:20 AM
dberlin added inline comments.
include/llvm/ADT/DepthFirstIterator.h
83

yes, it was consistency, i've changed it.

88–89

Nothing now.
To give some context, i was playing around with trying to transform the existence/non-existence into a bool template parameter that was inferred, so we wouldn't need the overload hack.
It turns out to be possible using constexpr functions, but doesn't seem to work in all compilers yet.

I've fixed this

dberlin marked 2 inline comments as done.
  • Update for review comments

Any chance of a unit test for this?

But as for the general design - yeah, this looks about like what I'd expect to see to achieve this. Hadn't seen the overload preference trick (int/bool) - and nice to see more decltype based SFINAE rather than all the trait goo we'd have had to have written in the past.

include/llvm/ADT/DepthFirstIterator.h
80

the 'return' here might be a bit misleading/confusing - since the return type of call_completed_method_imp is void, this statement is only valid if 'completed' returns void as well. Probably drop/remove the 'return' here.

I'll add a unit test.

FWIW, you can get rid of the overload hack, i just can't get it to work in all compilers.

You can now nice create a class that has a ::value of true or false if the method exists, but passing that as a template parameter doesn't work so well yet, and using constexpr functions to achieve the same goal doesn't quite work yet either.

dblaikie accepted this revision.Oct 20 2017, 12:14 PM

I'll add a unit test.

FWIW, you can get rid of the overload hack, i just can't get it to work in all compilers.

You can now nice create a class that has a ::value of true or false if the method exists,

Ah, yeah, I think I've written traits classes like that - but at least the ones I've done would take a lot more code (& eventually involve a similar overload set or the like) than this approach.

but passing that as a template parameter doesn't work so well yet, and using constexpr functions to achieve the same goal doesn't quite work yet either.