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?
