On 05/16/2017 08:50 AM, Nathan Sidwell wrote:
This patch implements new iterators for OVERLOADs. There are two
iterators:
ovl_iterator for a plain iterator, that held on a binding
lkp_iterator for the overload set returned by lookup.
To use them simply:
for (lkp_iterator iter (INIT); iter; ++iter)
{ tree fn = *iter;
... }
Currently the latter simply defers to the former, but I'll be changing
lookup so that it can return an overload of overloads. (Right now it
simply flattens things, which is sub-optimal).
This changes the easier cases of iteration to use these. I'll be
working through the other cases to convert them.
I've often wished for nice interfaces like this to get away from
the low level macros and make working with trees feel at least
a little bit like using C++ :) Thanks for making it possible!
Just a couple of suggestions, It looks like the classes model
the concept of Forward Iterator. May I suggest to make them
model it more closely and make them behave in unsurprising
ways to those familiar with the concept?
E.g., define both pre-increment and post-increment, define
the equality operator (as a non-member), etc., based on
C++ Forward Iterator requirements.
I'm not sure I understand why the ovl_iterator assignment needs
to be provided but if it does, not also defining one on the derived
class will call the base and return a reference to the base, making
the result no longer suitable where the derived is needed. This
is true for any other base members that return [a reference to]
the base type.
(If distinct types for iterators modeling the same concept
are necessary (or helpful) I would actually suggest to avoid
inheritance and instead introduce a generic iterator as
a template, and as many distinct [implicit] specializations
as necessary, with typedefs for each to make them look and
feel like classes.)
Martin
PS More descriptive names would be a nice as well (neither
lkp_ nor ovl_ is intuitive enough at first glance.) Maybe
lookup_iter and overload_iter?