Iteration methods for GLib containers
- From: Steve Lawler <mirrorsh atlantech net>
- To: gtk-devel-list gnome org
- Cc: mirrorsh atlantech net
- Subject: Iteration methods for GLib containers
- Date: Tue, 17 Apr 2001 11:33:45 -0400
If you're like me you hate to use special foreach/traverse routines
that are annoying to use (annoying because you have to write a
special-purpose traversal routine or wrapper routine just to iterate
through a collection). I vastly prefer to iterate in a for loop.
I wrote some code to create a "GIter" type that can be used to iterate
over arbitrary types of collections in a uniform manner. It works
like this:
{
GHashTable *hash;
GIter *hi;
gpointer key;
GKeyValue kv;
hash = g_hash_table_new(...);
/* Insert a bunch of stuff... */
/* Iterate over values */
for (foo = g_iter_first(&hi, hash, g_hash_table_iter);
foo;
foo = g_iter_next(hi))
{
/* do stuff */
}
g_iter_destroy(hi);
/* Iterate over keys */
for (key = g_iter_first_key(&hi, hash, g_hash_table_iter);
key; key = g_iter_next_key(hi)) ... etc
g_iter_destroy(hi);
/* Iterate over key/value pairs */
for (kv = g_iter_first_keyval(&hi, hash, g_hash_table_iter);
kv.value; kv = g_iter_next_keyval(hi)) ... etc
g_iter_destroy(hi);
/* Iterate through unknown data type w/ arbitrary method */
for (foo = g_iter_first(&hi, collection, collections_method);
etc...
}
This is much more preferable, at least to me, than...
typedef struct {
/* store everything random func needs... */
} random_struct;
static void random_func(gpointer key, gpointer value,
gpointer user_data)
{
/* cast pointers, do what we need to... */
}
{ ...
random_struct rs = { stack, blah };
g_hash_table_foreach(hash, random_func, &rs);
}
The idea is to have a generic "iterator" which provides a clean and
easy-to-use interface to any kind of collection. An "iteration method"
(which relies on intimate knowledge of the collection-type) provides a
way to iterate to the generic iterator interface (by providing functions
for init, next, prev, etc., methods). Conceivably collections could
have lots of different iteration methods. F.e., GTree could have
g_tree_iter_in_order, g_tree_iter_pre_order, etc, methods.
I've written code to provide iterators for GHashTables and a
g_tree_iter_pre_order method for GTree (which required minor
modification of the GTree data type, unfortunately, for efficient use
--- I didn't feel like building a stack during iteration so I added a
"parent" field to all GTreeNodes to avoid that). Adding other iteration
methods for other data types would be pretty easy.
The API might need some refinement, plus the code I wrote, but it's a
neat-ish hack, and makes working with GLib container types much more
enjoyable (I think).
If anyone is at all interested I will post mail the couple of source
files (approx. 11K I think) to the list.
-- Steve Lawler
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]