diff -x CVS -uNr glib.funcs/gobject/Makefile.am glib.gvalue/gobject/Makefile.am
--- glib.funcs/gobject/Makefile.am	Thu May 30 18:51:56 2002
+++ glib.gvalue/gobject/Makefile.am	Thu May 30 18:52:36 2002
@@ -77,6 +77,7 @@
 	gvalue.h		\
 	gvaluearray.h		\
 	gvaluecollector.h	\
+	gvalueiterator.h	\
 	gvaluetypes.h		\
 	gobjectnotifyqueue.c	\
 @STRIP_END@
@@ -98,6 +99,7 @@
 	gtypeplugin.c		\
 	gvalue.c		\
 	gvaluearray.c		\
+	gvalueiterator.c	\
 	gvaluetransform.c	\
 	gvaluetypes.c		\
 @STRIP_END@
@@ -191,18 +193,20 @@
 #
 bin_PROGRAMS = gobject-query glib-genmarshal
 bin_SCRIPTS = glib-mkenums
-noinst_PROGRAMS =  testgobject testoverride
+noinst_PROGRAMS =  testgobject testoverride testgvalueiterator
 # source files
 gobject_query_SOURCES = gobject-query.c
 glib_genmarshal_SOURCES = glib-genmarshal.c
 testgobject_SOURCES = testgobject.c
 testoverride_SOURCES = testoverride.c
+testgvalueiterator_SOURCES = testgvalueiterator.c
 # link programs against libgobject
 progs_LDADD = ./libgobject-2.0.la $(libglib)
 glib_genmarshal_LDADD = $(libglib)
 gobject_query_LDADD = $(progs_LDADD)
 testgobject_LDADD = $(progs_LDADD)
 testoverride_LDADD = $(progs_LDADD)
+testgvalueiterator_LDADD = $(progs_LDADD)
 
 #
 # manual pages to install
diff -x CVS -uNr glib.funcs/gobject/gvalueiterator.c glib.gvalue/gobject/gvalueiterator.c
--- glib.funcs/gobject/gvalueiterator.c	Wed Dec 31 16:00:00 1969
+++ glib.gvalue/gobject/gvalueiterator.c	Tue Feb  5 23:22:17 2002
@@ -0,0 +1,395 @@
+/* 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"
+#include "gvalue.h"
+#include "gvaluetypes.h"
+#include "genums.h"
+#include "gparam.h"
+#include "gboxed.h"
+#include "gobject.h"
+#include "gvalueiterator.h"
+
+
+
+/* Typedefs
+ */
+typedef struct _GIterCtxt GIterCtxt;
+
+
+
+/* Structures
+ */
+struct _GValueIterator
+{
+  gpointer context;
+  GIteratorFunc         has_more_func;
+  GValueIteratorFunc    get_next_func;
+  GDestroyNotify        notify_func;
+};
+
+struct _GIterCtxt
+{
+    GType               g_type;
+    GValueSetFunc       set_func;
+    GIterator          *iter;
+};
+
+
+
+/* Value Iterators
+ */
+
+/**
+ * g_value_iterator_new:
+ * @context: A context for the IteratorFuncs to work with.
+ * @has_more_func: A function that returns TRUE if the iterator has more items.
+ * @get_next_func: A function that sets the #GValue to the next item.
+ * @notify_func: An optional destroy function to clean up the context upon g_value_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 #GValueIterator.
+ */
+GValueIterator*
+g_value_iterator_new (gpointer           context,
+                      GIteratorFunc      has_more_func,
+                      GValueIteratorFunc get_next_func,
+                      GDestroyNotify     notify_func)
+{
+  GValueIterator *iter;
+
+  iter = g_new (GValueIterator, 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_value_iterator_new() */
+
+/**
+ * g_value_iterator_new_empty:
+ *
+ * Creates an iterator that always returns FALSE from the has_more_func.
+ *
+ * Return value: A new #GValueIterator.
+ */
+GValueIterator*
+g_value_iterator_new_empty (void)
+{
+    return g_value_iterator_new_from_g_iterator (g_iterator_new_empty (),
+                                                 G_TYPE_POINTER);
+}  /* g_value_iterator_new_empty() */
+
+/**
+ * g_value_iterator_has_more:
+ * @iter: The #GValueIterator to operate on.
+ *
+ * Query the #GValueIterator to see if there are more items.  This
+ * merely calls the implementor's has_more_func.
+ *
+ * Return value: TRUE if the #GValueIterator has more items.
+ */
+gboolean
+g_value_iterator_has_more (GValueIterator *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_value_iterator_has_more() */
+
+/**
+ * g_iterator_get_next:
+ * @iter: The #GValueIterator to operate on.
+ * @value: The #GValue to fill with the next item.
+ *
+ * Retrieve the next item in the #GValueIterator and place it in the
+ * provided GValue.  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.
+ */
+void
+g_value_iterator_get_next (GValueIterator *iter,
+                           GValue    *value)
+{
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (*iter->get_next_func != NULL);
+
+  if (G_IS_VALUE (value))
+    g_value_unset(value);
+  (*iter->get_next_func) (iter->context, value);
+}  /* g_value_iterator_get_next() */
+
+/**
+ * g_value_iterator_free:
+ * @iter: The #GValueIterator to free.
+ *
+ * Frees the #GValueIterator, calling the notify_func if it exists.
+ */
+void
+g_value_iterator_free (GValueIterator *iter)
+{
+  g_return_if_fail(iter != NULL);
+
+  if (*iter->notify_func != NULL)
+    (*iter->notify_func) (iter->context);
+
+  g_free(iter);
+}  /* g_value_iterator_free() */
+
+static gpointer
+g_value_iterator_g_iterator_has_more (gpointer context)
+{
+  GIterCtxt *ctxt;
+
+  g_return_val_if_fail (context != NULL, FALSE);
+
+  ctxt = (GIterCtxt *) context;
+
+  return (gpointer) g_iterator_has_more (ctxt->iter);
+}
+
+static void
+g_value_iterator_g_iterator_get_next (gpointer  context,
+                                      GValue   *value)
+{
+  GIterCtxt *ctxt;
+  gpointer result;
+
+  g_return_if_fail (context != NULL);
+  g_return_if_fail (value != NULL);
+
+  ctxt = (GIterCtxt *) context;
+
+  result = g_iterator_get_next (ctxt->iter);
+
+  g_value_init (value, ctxt->g_type);
+  (*ctxt->set_func) (value, result);
+}
+
+static void
+g_value_iterator_g_iterator_destroy_notify (gpointer context)
+{
+  GIterCtxt *ctxt;
+
+  g_return_if_fail (context != NULL);
+
+  ctxt = (GIterCtxt *) context;
+
+  g_iterator_free (ctxt->iter);
+  g_free(ctxt);
+}
+
+/**
+ * g_value_iterator_new_from_g_iterator:
+ * @iter: The #GIterator to use as a base.
+ * @type: The #GType for the returned values.
+ *
+ * Creates a new iterator object.  This object will retrieve its
+ * values from the passed #GIterator.  When it fills #GValue structures,
+ * it will use the passed #GType.
+ * 
+ * This convenience wrapper around
+ * g_value_iterator_new_from_g_iterator_full() guesses the proper
+ * bits to use based on the passed #GType.  This means the #GType has
+ * to be a fundamental type.  To create a #GValueIterator from a
+ * #GIterator with complex types, use
+ * g_value_iterator_new_from_g_iterator_full().
+ *
+ * In addition, it is worth noting that #GIterators cannot hold types
+ * of G_TYPE_DOUBLE, G_TYPE_INT64, and the like on platforms where
+ * gpointer is not big enough.  It can, of course, hold pointers to
+ * those types.
+ *
+ * Return value: A new #GValueIterator.
+ */
+GValueIterator*
+g_value_iterator_new_from_g_iterator(GIterator     *iter,
+                                     GType          g_type)
+{
+  GValueIterator *v_iter;
+  GValueSetFunc   set_func = NULL;
+
+  g_return_val_if_fail(G_TYPE_IS_VALUE (g_type),
+                       g_value_iterator_new_empty ());
+
+  /* If you have non-fundamental types, use
+   * g_value_iterator_new_from_g_iterator_full() and provide
+   * a set_func
+   */
+  g_return_val_if_fail(G_TYPE_IS_FUNDAMENTAL (g_type),
+                       g_value_iterator_new_empty ());
+
+  /* Types that aren't supported really */
+  g_return_val_if_fail((G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_INVALID) &&
+                       (G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_NONE) &&
+                       (G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_INTERFACE),
+                       g_value_iterator_new_empty ());
+
+  /* Types that can't fit in a GIterator gpointer */
+  g_return_val_if_fail((G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_INT64) &&
+                       (G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_UINT64) &&
+                       (G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_FLOAT) &&
+                       (G_TYPE_FUNDAMENTAL (g_type) !=
+                        G_TYPE_DOUBLE),
+                       g_value_iterator_new_empty ());
+
+  switch (g_type)
+  {
+      case G_TYPE_CHAR:
+          set_func = G_VALUE_SET_FUNC(g_value_set_char);
+          break;
+
+      case G_TYPE_UCHAR:
+          set_func = G_VALUE_SET_FUNC(g_value_set_uchar);
+          break;
+
+      case G_TYPE_BOOLEAN:
+          set_func = G_VALUE_SET_FUNC(g_value_set_boolean);
+          break;
+
+      case G_TYPE_INT:
+          set_func = G_VALUE_SET_FUNC(g_value_set_int);
+          break;
+
+      case G_TYPE_UINT:
+          set_func = G_VALUE_SET_FUNC(g_value_set_uint);
+          break;
+
+      case G_TYPE_LONG:
+          set_func = G_VALUE_SET_FUNC(g_value_set_long);
+          break;
+
+      case G_TYPE_ULONG:
+          set_func = G_VALUE_SET_FUNC(g_value_set_ulong);
+          break;
+
+      case G_TYPE_ENUM:
+          set_func = G_VALUE_SET_FUNC(g_value_set_enum);
+          break;
+
+      case G_TYPE_FLAGS:
+          set_func = G_VALUE_SET_FUNC(g_value_set_flags);
+          break;
+
+      case G_TYPE_STRING:
+          set_func = G_VALUE_SET_FUNC(g_value_set_string);
+          break;
+
+      case G_TYPE_POINTER:
+          set_func = G_VALUE_SET_FUNC(g_value_set_pointer);
+          break;
+
+      case G_TYPE_BOXED:
+          set_func = G_VALUE_SET_FUNC(g_value_set_boxed);
+          break;
+
+      case G_TYPE_PARAM:
+          set_func = G_VALUE_SET_FUNC(g_value_set_param);
+          break;
+
+      case G_TYPE_OBJECT:
+          set_func = G_VALUE_SET_FUNC(g_value_set_object);
+          break;
+
+
+      default:
+          g_assert_not_reached();
+          break;
+  }
+
+  v_iter = g_value_iterator_new_from_g_iterator_full (iter,
+                                                      g_type,
+                                                      set_func);
+  return v_iter;
+}
+
+/**
+ * g_value_iterator_new_from_g_iterator_full:
+ * @iter: The #GIterator to use as a base.
+ * @type: The #GType for the returned values.
+ * @set_fun: The function to set #GValues.
+ *
+ * Creates a new iterator object.  This object will retrieve its
+ * values from the passed #GIterator.  When it fills #GValue structures,
+ * it will use the passed #GType.  It sets the #GValue function with
+ * the given #GValueSetFunc.
+ * 
+ * It is worth noting that #GIterators cannot hold types
+ * of G_TYPE_DOUBLE, G_TYPE_INT64, and the like on platforms where
+ * gpointer is not big enough.  It can, of course, hold pointers to
+ * those types.
+ *
+ * Return value: A new #GValueIterator.
+ */
+GValueIterator*
+g_value_iterator_new_from_g_iterator_full (GIterator     *iter,
+                                           GType          g_type,
+                                           GValueSetFunc  set_func)
+{
+    GIterCtxt *ctxt;
+    GValueIterator *v_iter;
+
+    g_return_val_if_fail(G_TYPE_IS_VALUE_TYPE (g_type),
+                         g_value_iterator_new_empty ());
+
+    ctxt = g_new0(GIterCtxt, 1);
+    ctxt->g_type = g_type;
+    ctxt->set_func = set_func ? set_func : g_value_set_pointer;
+
+    if (!iter)
+      ctxt->iter = g_iterator_new_empty();
+    else
+      ctxt->iter = iter;
+
+    v_iter = g_value_iterator_new (ctxt,
+                                   g_value_iterator_g_iterator_has_more,
+                                   g_value_iterator_g_iterator_get_next,
+                                   g_value_iterator_g_iterator_destroy_notify);
+
+    return v_iter;
+}
diff -x CVS -uNr glib.funcs/gobject/gvalueiterator.h glib.gvalue/gobject/gvalueiterator.h
--- glib.funcs/gobject/gvalueiterator.h	Wed Dec 31 16:00:00 1969
+++ glib.gvalue/gobject/gvalueiterator.h	Tue Feb  5 23:08:45 2002
@@ -0,0 +1,71 @@
+/* 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_VALUE_ITERATOR_H__
+#define __G_VALUE_ITERATOR_H__
+
+#include <glib/gtypes.h>
+#include <glib/giterator.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GValueIterator	         GValueIterator;
+
+typedef void (*GValueIteratorFunc)      (gpointer  context,
+                                         GValue   *value);
+typedef void (*GValueSetFunc)           (GValue   *value,
+                                         gpointer  v_val);
+
+#define G_VALUE_SET_FUNC(v_func)        ((GValueSetFunc)(v_func))
+
+/* GIterator
+ */
+GValueIterator* g_value_iterator_new       (gpointer           context,
+                                            GIteratorFunc      has_more_func,
+                                            GValueIteratorFunc get_next_func,
+                                            GDestroyNotify     notify_func);
+
+GValueIterator* g_value_iterator_new_empty (void);
+
+GValueIterator* g_value_iterator_new_from_g_iterator (GIterator *iter,
+                                                      GType      g_type);
+
+GValueIterator* g_value_iterator_new_from_g_iterator_full (GIterator    *iter,
+                                                           GType         g_type,
+                                                           GValueSetFunc set_func);
+
+gboolean        g_value_iterator_has_more  (GValueIterator      *iter);
+
+void            g_value_iterator_get_next  (GValueIterator      *iter,
+                                            GValue              *value);
+
+void	        g_value_iterator_free	   (GValueIterator      *iter);
+
+
+G_END_DECLS
+
+#endif /* __G_VALUE_STRING_H__ */
+
diff -x CVS -uNr glib.funcs/gobject/testgvalueiterator.c glib.gvalue/gobject/testgvalueiterator.c
--- glib.funcs/gobject/testgvalueiterator.c	Wed Dec 31 16:00:00 1969
+++ glib.gvalue/gobject/testgvalueiterator.c	Fri May 31 09:43:10 2002
@@ -0,0 +1,83 @@
+#include <stdio.h>
+
+#include "glib.h"
+#include "gvalue.h"
+#include "gvaluetypes.h"
+#include "gvalueiterator.h"
+
+
+static void dbl_set(GValue *val, gpointer v_val)
+{
+    g_value_set_double(val, *(gdouble *)v_val);
+}
+
+
+int main(int argc, char *argv[])
+{
+    GList *list;
+    gdouble dbls[] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9};
+    GIterator *iter;
+    GValueIterator *v_iter;
+    GValue val = {0, };
+    gint i;
+    gchar c;
+
+    g_type_init();
+
+    for (i = 'a', list = NULL; i < 'j'; i++)
+        list = g_list_append(list, (gpointer)i);
+
+    iter = g_list_iterate(list);
+    fprintf(stderr, "List iterate... ");
+    while (g_iterator_has_more(iter))
+    {
+        c = (gchar)g_iterator_get_next(iter);
+        fprintf(stderr, "%c ", c);
+    }
+    g_iterator_free(iter);
+    fprintf(stderr, "done\n");
+
+    iter = g_list_iterate(list);
+    v_iter = g_value_iterator_new_from_g_iterator(iter, G_TYPE_CHAR);
+    fprintf(stderr, "Value iterate... ");
+    while (g_value_iterator_has_more(v_iter))
+    {
+        g_value_iterator_get_next(v_iter, &val);
+        if (G_VALUE_TYPE(&val) != G_TYPE_CHAR)
+        {
+            fprintf(stderr, "Error: Value is of type %s\n",
+                    G_VALUE_TYPE_NAME(&val));
+            break;
+        }
+        fprintf(stderr, "%c ", g_value_get_char(&val));
+    }
+    g_value_iterator_free(v_iter);
+    fprintf(stderr, "done\n");
+
+    g_list_free(list);
+
+    for (i = 0, list = NULL; i < (sizeof(dbls) / sizeof(dbls[0])); i++)
+        list = g_list_append(list, &(dbls[i]));
+
+    iter = g_list_iterate(list);
+    fprintf(stderr, "Value iterate full... ");
+    v_iter = g_value_iterator_new_from_g_iterator_full(iter,
+                                                       G_TYPE_DOUBLE,
+                                                       dbl_set);
+    while (g_value_iterator_has_more(v_iter))
+    {
+        g_value_iterator_get_next(v_iter, &val);
+        if (G_VALUE_TYPE(&val) != G_TYPE_DOUBLE)
+        {
+            fprintf(stderr, "Error: Value is of type %s\n",
+                    G_VALUE_TYPE_NAME(&val));
+            break;
+        }
+        fprintf(stderr, "%1.1f ", g_value_get_double(&val));
+    }
+    g_value_iterator_free(v_iter);
+    fprintf(stderr, "done\n");
+
+    return(0);
+}
+
