diff -x CVS -uNr glib.orig/glib/Makefile.am glib.core/glib/Makefile.am
--- glib.orig/glib/Makefile.am	Mon Mar  4 21:17:39 2002
+++ glib.core/glib/Makefile.am	Thu Mar 14 19:08:31 2002
@@ -50,6 +50,7 @@
 	ghash.c			\
 	ghook.c			\
 	giochannel.c    	\
+	giterator.c		\
 	glibintl.h		\
 	glist.c			\
 	gmain.c         	\
@@ -113,6 +114,7 @@
 	ghash.h		\
 	ghook.h		\
 	giochannel.h	\
+	giterator.h	\
 	glist.h		\
 	gmacros.h	\
 	gmain.h		\
diff -x CVS -uNr glib.orig/glib/giterator.c glib.core/glib/giterator.c
--- glib.orig/glib/giterator.c	Wed Dec 31 16:00:00 1969
+++ glib.core/glib/giterator.c	Sun Feb  3 00:39:31 2002
@@ -0,0 +1,171 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe - The implementor of the has_more/get_next functions is
+ *           responsible for the true MT safety of a GIterator.
+ */
+
+#include "glib.h"
+
+
+
+/* Structures
+ */
+struct _GIterator
+{
+  gpointer context;
+  GIteratorFunc         has_more_func;
+  GIteratorFunc         get_next_func;
+  GDestroyNotify        notify_func;
+};
+
+
+
+/* Prototypes
+ */
+static gpointer          g_iterator_false (gpointer thrway);
+
+
+
+/* Iterators
+ */
+
+/**
+ * g_iterator_new:
+ * @context: A context for the GIteratorFuncs to work with.
+ * @has_more_func: A function that returns TRUE if the iterator has more items.
+ * @get_next_func: A function that returns the next item.
+ * @notify_func: An optional destroy function to clean up the context upon g_iterator_free().
+ *
+ * Creates a new iterator object with the specified context and
+ * functions.  Iterator users should never see this, it is called by
+ * the implementor of the iterator.
+ *
+ * Return value: A new #GIterator.
+ */
+GIterator*
+g_iterator_new (gpointer                context,
+                GIteratorFunc           has_more_func,
+                GIteratorFunc           get_next_func,
+                GDestroyNotify          notify_func)
+{
+  GIterator *iter;
+
+  iter = g_new (GIterator, 1);
+  iter->context = context;
+  iter->has_more_func = has_more_func;
+  iter->get_next_func = get_next_func;
+  iter->notify_func = notify_func;
+
+  return iter;
+}  /* g_iterator_new() */
+
+/* This function simply returns FALSE for g_iterator_new_empty() */
+static gpointer
+g_iterator_false (gpointer thrway)
+{
+    return (gpointer) FALSE;
+}  /* g_iterator_false() */
+
+/**
+ * g_iterator_new_empty:
+ *
+ * Creates an iterator that always returns FALSE from the has_more_func.
+ *
+ * Return value: A new #GIterator.
+ */
+GIterator*
+g_iterator_new_empty (void)
+{
+    return g_iterator_new(NULL, g_iterator_false, NULL, NULL);
+}  /* g_iterator_new_empty() */
+
+/**
+ * g_iterator_has_more:
+ * @iter: The #GIterator to operate on.
+ *
+ * Query the #GIterator to see if there are more items.  This merely 
+ * calls the implementor's has_more_func.
+ *
+ * Return value: TRUE if the #GIterator has more items.
+ */
+gboolean
+g_iterator_has_more (GIterator *iter)
+{
+  gpointer result;
+
+  g_return_val_if_fail (iter != NULL, FALSE);
+
+  if (*iter->has_more_func != NULL)
+    result = (*iter->has_more_func) (iter->context);
+  else
+    result = (gpointer) FALSE;
+
+  return (gboolean) result;
+}  /* g_iterator_has_more() */
+
+/**
+ * g_iterator_get_next:
+ * @iter: The #GIterator to operate on.
+ *
+ * Retrieve the next item in the #GIterator.  This is undefined if
+ * has_more is FALSE.  This merely calls the implementor's get_next_func.
+ * Note that the context pointer is not modifiable by the get_next_func.
+ *
+ * Return value: TRUE if the #GIterator has more items.
+ */
+gpointer
+g_iterator_get_next (GIterator *iter)
+{
+  gpointer result;
+
+  g_return_val_if_fail (iter != NULL, NULL);
+  g_return_val_if_fail (*iter->get_next_func != NULL, NULL);
+
+  result = (*iter->get_next_func) (iter->context);
+
+  return result;
+}  /* g_iterator_get_next() */
+
+/**
+ * g_iterator_free:
+ * @iter: The #GIterator to free.
+ *
+ * Frees the #GIterator, calling the notify_func if it exists.
+ */
+void
+g_iterator_free (GIterator *iter)
+{
+  g_return_if_fail(iter != NULL);
+
+  if (*iter->notify_func != NULL)
+    (*iter->notify_func) (iter->context);
+
+  g_free(iter);
+}  /* g_iterator_free() */
+
+
diff -x CVS -uNr glib.orig/glib/giterator.h glib.core/glib/giterator.h
--- glib.orig/glib/giterator.h	Wed Dec 31 16:00:00 1969
+++ glib.core/glib/giterator.h	Sat Feb  2 22:51:18 2002
@@ -0,0 +1,58 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __G_ITERATOR_H__
+#define __G_ITERATOR_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GIterator		GIterator;
+
+typedef gpointer (*GIteratorFunc)	(gpointer context);
+
+
+/* GIterator
+ */
+GIterator* g_iterator_new               (gpointer        context,
+                                         GIteratorFunc   has_more_func,
+                                         GIteratorFunc   get_next_func,
+                                         GDestroyNotify	 notify_func);
+
+GIterator* g_iterator_new_empty         (void);
+
+gboolean   g_iterator_has_more		(GIterator	*iter);
+
+gpointer   g_iterator_get_next		(GIterator	*iter);
+
+void	   g_iterator_free		(GIterator	*iter);
+
+
+G_END_DECLS
+
+#endif /* __G_STRING_H__ */
+
diff -x CVS -uNr glib.orig/glib/glib.h glib.core/glib/glib.h
--- glib.orig/glib/glib.h	Sun Nov  4 17:47:31 2001
+++ glib.core/glib/glib.h	Thu Jan 31 19:27:36 2002
@@ -42,6 +42,7 @@
 #include <glib/ghash.h>
 #include <glib/ghook.h>
 #include <glib/giochannel.h>
+#include <glib/giterator.h>
 #include <glib/glist.h>
 #include <glib/gmacros.h>
 #include <glib/gmain.h>
diff -x CVS -uNr glib.orig/tests/testglib.c glib.core/tests/testglib.c
--- glib.orig/tests/testglib.c	Thu May 30 18:47:16 2002
+++ glib.core/tests/testglib.c	Thu May 30 18:51:24 2002
@@ -307,6 +307,40 @@
   return FALSE;
 }
 
+static gpointer
+my_iterate_next (gpointer context)
+{
+    int *i;
+    int r;
+
+    i = (int *) context;
+
+    r = *i;
+    *i += 1;
+
+    return (gpointer) r;
+}
+
+static gpointer
+my_iterate_has (gpointer context)
+{
+    int *i;
+
+    i = (int *) context;
+
+    return (gpointer) (*i < 10);
+}
+
+static void
+my_iterate_free (gpointer context)
+{
+    int *i;
+
+    i = (int *) context;
+
+    g_free(i);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -331,6 +365,7 @@
   char chars[62];
   GRelation *relation;
   GTuples *tuples;
+  GIterator *iter;
   gint data [1024];
   struct {
     gchar *filename;
@@ -746,6 +781,20 @@
   g_print ("ok\n");
 
 
+  g_print ("checking iterators... ");
+
+  iter = g_iterator_new (g_new0(int, 1),
+                              my_iterate_has,
+                              my_iterate_next,
+                              my_iterate_free);
+  while (g_iterator_has_more (iter))
+      g_print ("%d ", (int) g_iterator_get_next (iter));
+
+  g_iterator_free (iter);
+
+  g_print ("ok\n");
+
+
   g_print ("checking string chunks...");
 
   string_chunk = g_string_chunk_new (1024);
@@ -1156,6 +1205,7 @@
 
   g_byte_array_free (gbarray, TRUE);
   g_print ("ok\n");
+
 
   g_printerr ("g_log tests:");
   g_warning ("harmless warning with parameters: %d %s %#x", 42, "Boo", 12345);
