GNOME Bugzilla – Bug 83729
Patches to add iterators to GLib
Last modified: 2011-02-18 16:07:08 UTC
[ Copy from gtk-devel-list post ] Iterators for GLib and GObject Ok, here are my thoughts on iterators for GLib. First, a couple of terms. I am discussing iterators as Python or Java use them. My original code was based on Java's Enumeration interface, and is now based loosely on the Iterator interface. Python iterators behave similarly. When I speak of an iterator "user," I do not mean a person implementing an iterator. That person I refer to as the "implementor." The point of an iterator is that the person retrieving an iterator from a provided API (the "user") does not have any idea how it is implemented. They only know the access functions for iterators. If this isn't clear, hopefully it will become more clear as this document progresses ;-) I got going on this from the great debate about returning static versus allocated constructs. The discussion mostly revolved around returning static strings vs g_strdup()ing them. The subject of allocated vs static GList returns was brought up but not really discussed. At the time, various GTK+ API returned GLists, and they varied whether you were required to free the list. We've improved that a lot now, thank heavens. In providing an iterator structure, I generally had the following goals in mind: o The implementor should have flexible control over how the iterator behaves. o People linking libgobject should be able to take advantage of GValue. o There should be usable iterators for people only linking libglib. o The interface should be similar whether GValue is being used or not. I looked at trying to use the same exact API for GValue and non-GValue iterators, but it ended up being non-obvious how to do it cleanly. The generic use is: --8<-------------------------------------------------------------- iter = foo_something_iterate(foo); while (g_iterator_has_more(iter)) { item = (FooItem *)g_iterator_get_next(iter); do_something(item); } g_iterator_free(iter); v_iter = foo_something_else_iterate(foo); while (g_value_iterator_has_more(v_iter); { g_value_iterator_get_next(v_iter, &gvalue); do_something_else(gvalue); } g_value_iterator_free(v_iter); -->8-------------------------------------------------------------- I've also added some nice convenience functions to do things like iterate GLists and create a GValueIterator from a GIterator. As a side effect of the implementation, "generators" ala python are also quite possible. There is an example of a generator in testglib.c. Three patches are attached. They are all against GLib HEAD. The first (glib-2.0.3-giterator-00-iterator-core.patch) provides the core GIterator data structure. The second (glib-2.0.3-iterator-10-giterator-funcs.patch) provides various convenience functions to other parts of GLib. The third (glib-2.0.3-iterator-20-giterator-gvalue.patch) adds GValueIterator. These patches are also in Bugzilla against the BugID #000000. Please have a look at this. Folks who are interested, please make your interest known. I'm open to any and all feedback. I myself use a variation of the GIterator code in three different projects and I enjoy the flexibility it provides. I think it would be a useful addition to GLib.
Created attachment 8893 [details] [review] Core GIterator code
Created attachment 8894 [details] [review] GIterator convenience functions
Created attachment 8895 [details] [review] GValueIterator code
*** Bug 52084 has been marked as a duplicate of this bug. ***
Pushing off to 2.4 API freeze, since it's definitely too late for 2.2 now. But I will say that I'm not particularly in favor of this addition ... not that iterators are a bad idea, but I can't see how adding something this fundamental at this stage in the GLib/GTK+ could ever be anything but an yet-another-way-to-do-it and a source of further inconsistency in our APIs. I'll try to write this up more formally and send a mail about that to gtk-devel-list early in the 2.4 cycle.
One argument in favour of iterators on hash tables that I've seen on the lists recently is that g_hashtable_foreach isn't cancelable. Maybe we can sneak this in by changing the signature of GHFunc to return a boolean...
Can't add a return value to GHFunc ... that's not a compatible change. My feeling about cancelling iteration on GHashTable is that it at most saves you 50% of your time... 0.5 * O(n) is still O(n). Just sent a writeup of my opinion as to why this is WONTFIX to gtk-devel-list: http://mail.gnome.org/archives/gtk-devel-list/2004-January/msg00242.html