? ChangeLog.conflict
? gtk_docs.xml
? gtkmm.kdevprj
? gtkmm.kdevses
? gtkmm_libsigc.patch
? gtkmm_sigc2.patch
? gtkmm_treemodel_constiter.patch
? gtkmm_treemodel_constiter2.patch
? temp.diff
? temp.patch
? temp.pathc
? temp.txt
? temp_constiter.patch
? docs/reference/doxygen_warnings.txt
? examples/book/treeview/list/temp.patch
? examples/cellrenderercustom/popupentry.cc.conflict
? examples/dnd/dndwindow.cc.conflict
? examples/treemodelcustom/core.26952
? examples/treemodelcustom/core.29612
? examples/treemodelcustom/core.30866
? examples/treemodelcustom/core.30867
? gtk/temp.patch
? gtk/gtkmm/celllayout.loT
? gtk/gtkmm/fileselection.loT
? tests/treemodel_const_iterator
? tools/gtk_enums.defs
? tools/temp.diff
? tools/extra_defs_gen/enums.defs
? tools/extra_defs_gen/gtk.defs
? tools/extra_defs_gen/temp.defs
? tools/extra_defs_gen/temp.patch
? tools/extra_defs_gen/temp2.defs
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gtkmm/configure.in,v
retrieving revision 1.24
diff -u -p -r1.24 configure.in
--- configure.in	26 Feb 2004 22:49:06 -0000	1.24
+++ configure.in	29 Feb 2004 16:33:53 -0000
@@ -276,6 +276,7 @@ AC_CONFIG_FILES([
     tests/delete_cpp_child/Makefile
     tests/menu_destruction/Makefile
     tests/scrolledwindow/Makefile
+    tests/treemodel_const_iterator/Makefile
     tests/wrap_existing/Makefile
 ])
 
Index: gtk/gtkmm/treeview_private.cc
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/gtkmm/treeview_private.cc,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 treeview_private.cc
--- gtk/gtkmm/treeview_private.cc	21 Jan 2003 13:40:59 -0000	1.1.1.1
+++ gtk/gtkmm/treeview_private.cc	29 Feb 2004 16:33:54 -0000
@@ -43,7 +43,7 @@ void SignalProxy_CellData::gtk_callback(
   try
   {
     // use Slot::operator()
-    (self->slot_)(Glib::wrap(cell, false), TreeIter(model, iter));
+    (self->slot_)(Glib::wrap(cell, false), TreeModel::iterator(model, iter));
   }
   catch(...)
   {
Index: gtk/src/celllayout.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/celllayout.ccg,v
retrieving revision 1.5
diff -u -p -r1.5 celllayout.ccg
--- gtk/src/celllayout.ccg	26 Feb 2004 22:59:50 -0000	1.5
+++ gtk/src/celllayout.ccg	29 Feb 2004 16:33:54 -0000
@@ -18,6 +18,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <gtkmm/treeiter.h>
 #include <gtk/gtkcelllayout.h>
 
 
Index: gtk/src/entrycompletion.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/entrycompletion.ccg,v
retrieving revision 1.8
diff -u -p -r1.8 entrycompletion.ccg
--- gtk/src/entrycompletion.ccg	26 Feb 2004 22:59:50 -0000	1.8
+++ gtk/src/entrycompletion.ccg	29 Feb 2004 16:33:54 -0000
@@ -185,7 +185,7 @@ bool Gtk::EntryCompletion::on_match_sele
   );
 
   if(base && base->match_selected)
-    return (*base->match_selected)(gobj(), iter.get_model_gobject(), const_cast<GtkTreeIter*>(iter.gobj()));
+    return (*base->match_selected)(gobj(), const_cast<GtkTreeModel*>(iter.get_model_gobject()), const_cast<GtkTreeIter*>(iter.gobj()));
   else
   {
     typedef bool RType;
Index: gtk/src/liststore.hg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/liststore.hg,v
retrieving revision 1.3
diff -u -p -r1.3 liststore.hg
--- gtk/src/liststore.hg	20 Jan 2004 17:48:10 -0000	1.3
+++ gtk/src/liststore.hg	29 Feb 2004 16:33:54 -0000
@@ -127,7 +127,7 @@ public:
 
   _WRAP_METHOD(void clear(), gtk_list_store_clear)
 
-  _WRAP_METHOD(bool iter_is_valid(const iterator& iter) const, gtk_list_store_iter_is_valid)
+  _WRAP_METHOD(bool iter_is_valid(const const_iterator& iter) const, gtk_list_store_iter_is_valid)
 
 protected:
   virtual void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value);
Index: gtk/src/treeiter.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treeiter.ccg,v
retrieving revision 1.7
diff -u -p -r1.7 treeiter.ccg
--- gtk/src/treeiter.ccg	26 Feb 2004 22:28:25 -0000	1.7
+++ gtk/src/treeiter.ccg	29 Feb 2004 16:33:54 -0000
@@ -24,18 +24,18 @@ namespace //anonymous
 {
 
 //This is copied from Totem. In future there might be a version in GTK+ itself - see bug #
-static gboolean gtkmm_gtk_tree_model_iter_previous (GtkTreeModel *tree_model, GtkTreeIter *iter)
+gboolean gtkmm_gtk_tree_model_iter_previous (GtkTreeModel *tree_model, GtkTreeIter *iter)
 {
-	GtkTreePath *path;
-	gboolean ret;
+  GtkTreePath *path;
+  gboolean ret;
 
-	path = gtk_tree_model_get_path (tree_model, iter);
-	ret = gtk_tree_path_prev (path);
-	if (ret == TRUE)
-		gtk_tree_model_get_iter (tree_model, iter, path);
+  path = gtk_tree_model_get_path (tree_model, iter);
+  ret = gtk_tree_path_prev (path);
+  if (ret == TRUE)
+    gtk_tree_model_get_iter (tree_model, iter, path);
 
-	gtk_tree_path_free (path);
-	return ret;
+  gtk_tree_path_free (path);
+  return ret;
 }
 
 } //anonymous namespace
@@ -43,130 +43,57 @@ static gboolean gtkmm_gtk_tree_model_ite
 namespace Gtk
 {
 
-/**** Gtk::TreeIter ********************************************************/
+/**** Gtk::TreeIterBase ****/
 
-TreeIter::TreeIter()
-:
-  TreeIterBase(),
-  model_      (0),
-  is_end_     (false)
-{}
-
-TreeIter::TreeIter(TreeModel* model)
-:
-  TreeIterBase(),
-  model_      (model),
-  is_end_     (false)
-{}
-
-TreeIter::TreeIter(GtkTreeModel* model, const GtkTreeIter* iter)
-:
-  TreeIterBase(iter),
-  model_      (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model))),
-  is_end_     (iter == 0)
-{}
-
-TreeIter& TreeIter::operator++()
+// static
+GType TreeIterBase::get_type()
 {
-  g_assert(!is_end_);
-
-  GtkTreeIter previous = gobject_;
-
-  if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
-  {
-    is_end_ = true;
-    gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous);
-  }
-
-  return *this;
+  return gtk_tree_iter_get_type();
 }
 
-const TreeIter TreeIter::operator++(int)
+TreeIterBase::TreeIterBase()
+: model_(0),
+  is_end_(false)
 {
-  g_assert(!is_end_);
-
-  TreeIter previous (*this);
-
-  if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
-  {
-    is_end_ = true;
-    gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous.gobject_);
-  }
-
-  return previous;
+  GLIBMM_INITIALIZE_STRUCT(gobject_, GtkTreeIter);
 }
 
-TreeIter& TreeIter::operator--()
+TreeIterBase::TreeIterBase(const GtkTreeIter* gobject)
+: model_(0),
+  is_end_(gobject == 0)
 {
-  g_assert(!is_end_);
-
-  GtkTreeIter previous = gobject_;
-
-  if(!gtkmm_gtk_tree_model_iter_previous(model_->gobj(), &gobject_))
-  {
-    is_end_ = true;
-    gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous);
-  }
-
-  return *this;
+  if(gobject)
+    gobject_ = *gobject;
+  else
+    GLIBMM_INITIALIZE_STRUCT(gobject_, GtkTreeIter);
 }
 
-const TreeIter TreeIter::operator--(int)
+void TreeIterBase::set_model_refptr(const Glib::RefPtr<TreeModel>& model)
 {
-  g_assert(!is_end_);
-
-  TreeIter previous (*this);
-
-  if(!gtkmm_gtk_tree_model_iter_previous(model_->gobj(), &gobject_))
-  {
-    is_end_ = true;
-    gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous.gobject_);
-  }
-
-  return previous;
+  model_ = model.operator->();
 }
 
-/* There is no public gtk_tree_iter_equal(), so we must write our own.
- */
-bool TreeIter::equal(const TreeIter& other) const
+void TreeIterBase::set_model_gobject(GtkTreeModel* model)
 {
-  g_assert(model_ == other.model_);
+  model_ = dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model));
+}
 
-  // A GtkTreeIter has the same stamp value as its model.
-  g_assert(gobject_.stamp == other.gobject_.stamp || is_end_ || other.is_end_);
+GtkTreeModel* TreeIterBase::get_model_gobject() const
+{
+  return (model_) ? model_->gobj() : 0;
+}
 
-  // If all user_data pointers are equal we can assume the iterators to be
-  // equal.  This should be safe since GtkTreeIter lacks destroy notification,
-  // thus there is no way to attach more data fields to the iterator.
-  return (is_end_ == other.is_end_) &&
-         (gobject_.user_data  == other.gobject_.user_data)  &&
-         (gobject_.user_data2 == other.gobject_.user_data2) &&
-         (gobject_.user_data3 == other.gobject_.user_data3);
+int TreeIterBase::get_stamp() const
+{
+  return gobj()->stamp;
 }
 
-TreeIter::operator bool() const
+void TreeIterBase::set_stamp(int stamp)
 {
-  if(is_end_)
-    return false;
-    
-  if(model_)
-    return model_->iter_is_valid(*this);
-  else
-  {
-    g_warning("Gtk::TreeIter::operator bool(): defaulting to false because this iterator has no TreeModel.");
-    return false; //This should never happen, but let's not segfault if it does.
-  }
-  
-  //This is what we did before we had the iter_is_valid() method:
-  //we still use it in the default implementation of TreeModel::iter_is_valid().
-  //  
-  // Test whether the GtkTreeIter is valid and not an end iterator.  This check
-  // is almost the same as the private VALID_ITER() macro in gtkliststore.c and
-  // gtktreestore.c.
-  //return (!is_end_ && gobject_.stamp != 0);
+  gobj()->stamp = stamp;
 }
 
-void TreeIter::setup_end_iterator(const TreeIter& last_valid)
+void TreeIterBase::setup_end_iterator(const TreeIterBase& last_valid)
 {
   g_assert(model_ == last_valid.model_);
 
@@ -178,45 +105,75 @@ void TreeIter::setup_end_iterator(const 
   is_end_ = true;
 }
 
-void TreeIter::set_model_refptr(const Glib::RefPtr<TreeModel>& model)
+void TreeIterBase::iter_next()
 {
-  model_ = model.operator->();
-}
+   g_assert(!is_end_);
 
-void TreeIter::set_model_gobject(GtkTreeModel* model)
-{
-  model_ = dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model));
-}
+   GtkTreeIter previous = gobject_;
 
-GtkTreeModel* TreeIter::get_model_gobject() const
-{
-  return (model_) ? model_->gobj() : 0;
+   if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
+   {
+     is_end_ = true;
+     
+     //If there was no next, then we set it to the parent instead.
+     //TODO: Why do we do this? murrayc.
+     gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous);
+   }
 }
 
-
-int TreeIter::get_stamp() const
+void TreeIterBase::iter_previous()
 {
-  return gobj()->stamp;
-}
+  g_assert(!is_end_);
 
-void TreeIter::set_stamp(int stamp)
-{
-  gobj()->stamp = stamp;
-} 
+  GtkTreeIter previous = gobject_;
+
+  if(!gtkmm_gtk_tree_model_iter_previous(model_->gobj(), &gobject_))
+  {
+    is_end_ = true;
 
+    //If there was no previous, then we set it to the parent instead.
+    //TODO: Why do we do this? murrayc.
+    gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous);
+  }
+}
 
+  
+ 
 /**** Gtk::TreeRow *********************************************************/
 
+TreeNodeChildren::iterator TreeNodeChildren::get_iterator()
+{
+  //TODO
+  return iterator();
+}
+TreeNodeChildren::const_iterator TreeNodeChildren::get_iterator() const
+{
+  //TODO
+  return const_iterator();
+}
+  
 const TreeNodeChildren& TreeRow::children() const
 {
   g_assert(!is_end_);
 
-  return static_cast<const TreeNodeChildren&>(static_cast<const TreeIter&>(*this));
+  return static_cast<const TreeNodeChildren&>(static_cast<const _Base&>(*this));
 }
 
-TreeIter TreeRow::parent() const
+TreeRow::iterator TreeRow::parent()
 {
-  TreeIter iter (model_);
+  iterator iter (model_);
+
+  if(is_end_)
+    iter.gobject_ = gobject_;
+  else
+    gtk_tree_model_iter_parent(model_->gobj(), iter.gobj(), const_cast<GtkTreeIter*>(&gobject_));
+
+  return iter;
+}
+
+TreeRow::const_iterator TreeRow::parent() const
+{
+  const_iterator iter (model_);
 
   if(is_end_)
     iter.gobject_ = gobject_;
@@ -238,7 +195,7 @@ void TreeRow::get_value_impl(int column,
 
 TreeRow::operator bool() const
 {
-  return TreeIter::operator bool();
+  return _Base::operator bool();
 }
 
 
@@ -246,7 +203,7 @@ TreeRow::operator bool() const
 
 TreeNodeChildren::iterator TreeNodeChildren::begin()
 {
-  iterator iter (model_);
+  iterator iter(model_);
 
   // If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
   // node.  This behaviour is needed to implement Gtk::TreeModel::children().
@@ -274,9 +231,9 @@ TreeNodeChildren::iterator TreeNodeChild
 
 TreeNodeChildren::const_iterator TreeNodeChildren::begin() const
 {
-  //TODO: Reduce the copy/paste from the non-const begin()?
+  //TODO: There is some unpleasant copy/pasting of code here, from the non-const begin():
   
-  const_iterator iter (model_);
+  const_iterator iter(model_);
 
   // If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
   // node.  This behaviour is needed to implement Gtk::TreeModel::children().
@@ -302,6 +259,7 @@ TreeNodeChildren::const_iterator TreeNod
   return iter;
 }
 
+
 TreeNodeChildren::iterator TreeNodeChildren::end()
 {
   // Just copy the parent, and turn it into an end iterator.
@@ -312,6 +270,8 @@ TreeNodeChildren::iterator TreeNodeChild
 
 TreeNodeChildren::const_iterator TreeNodeChildren::end() const
 {
+  //TODO: There is some unpleasant copy/pasting of code here, from the non-const begin():
+
   // Just copy the parent, and turn it into an end iterator.
   const_iterator iter (*this);
   iter.is_end_ = true;
@@ -320,7 +280,7 @@ TreeNodeChildren::const_iterator TreeNod
 
 TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index) const
 {
-  iterator iter (model_);
+  iterator iter(model_);
 
   GtkTreeIter *const parent = const_cast<GtkTreeIter*>(get_parent_gobject());
 
Index: gtk/src/treeiter.hg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treeiter.hg,v
retrieving revision 1.10
diff -u -p -r1.10 treeiter.hg
--- gtk/src/treeiter.hg	26 Feb 2004 22:28:25 -0000	1.10
+++ gtk/src/treeiter.hg	29 Feb 2004 16:33:55 -0000
@@ -19,19 +19,34 @@
 
 _DEFS(gtkmm,gtk)
 
+//#include <gtkmm/treemodel.h>
 #include <gtkmm/treemodelcolumn.h>
 #include <gtkmmconfig.h>
 #include <iterator>
 #include <gtk/gtktreemodel.h> /* for GtkTreeIter */
 
+
 GLIBMM_USING_STD(forward_iterator_tag)
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+namespace //anonymous
+{
+
+//This is copied from Totem. In future there might be a version in GTK+ itself - see bug #
+gboolean gtkmm_gtk_tree_model_iter_previous (GtkTreeModel *tree_model, GtkTreeIter *iter);
+
+} //namespace
+#endif //DOXYGEN_SHOULD_SKIP_THIS
 
 namespace Gtk
 {
 
 class TreeModel;
+
+template<class _Tp, class _Ref, class _Ptr>
 class TreeRow;
+
+template<class _Tp, class _Ref, class _Ptr>
 class TreeNodeChildren;
 
 /**
@@ -39,9 +54,111 @@ class TreeNodeChildren;
  */
 class TreeIterBase
 {
-  _CLASS_BOXEDTYPE_STATIC(TreeIterBase, GtkTreeIter)
-  _IGNORE(gtk_tree_iter_copy, gtk_tree_iter_free)
- _NO_WRAP_FUNCTION() //A wrap() for TreeIterBase* wouldn't be very helpful.
+  public:
+  
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  typedef TreeIterBase CppObjectType;
+  typedef GtkTreeIter BaseObjectType;
+
+  static GType get_type() G_GNUC_CONST;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+  TreeIterBase();
+  
+  explicit TreeIterBase(const GtkTreeIter* gobject); // always takes a copy
+
+  /** This is only useful when implementing a custom Gtk::TreeModel class.
+   * Compare the iterator's stamp with your model's stamp to discover whether it is valid.
+   * @see set_stamp().
+   * @result The iterator's stamp.
+   */
+  int get_stamp() const;
+
+  /** This is only useful when implementing a custom Gtk::TreeModel class.
+   * Set the stamp to be equal to your model's stamp, to mark the iterator as valid.
+   * When your model's structure changes, you should increment your model's stamp
+   * to mark all older iterators as invalid. They will be recognised as invalid because
+   * they will then have an incorrect stamp.
+   * @param stamp The model's current stamp value.
+   */
+  void set_stamp(int stamp);
+
+  ///Provides access to the underlying C instance.
+  GtkTreeIter*       gobj()       { return &gobject_; }
+
+  ///Provides access to the underlying C instance.
+  const GtkTreeIter* gobj() const { return &gobject_; }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+  void setup_end_iterator(const TreeIterBase& last_valid);
+  
+  void set_model_refptr(const Glib::RefPtr<TreeModel>& model);
+  void set_model_gobject(GtkTreeModel* model);
+
+  //TODO: Maybe this should not be const, but
+  //if it returned a const GtkTreeModel* then we could not store
+  //the result as a non-const GtkTreeModel - for instance, in
+  //TreePath::TreePath(const TreeModel::iterator& iter).
+  //I'm not sure what to do about that. murrayc.
+  GtkTreeModel* get_model_gobject() const;
+
+  const GtkTreeIter* get_gobject_if_not_end() const
+    { return (!is_end_) ? &gobject_ : 0; }
+
+  const GtkTreeIter* get_parent_gobject_if_end() const
+    { return (is_end_ && gobject_.stamp) ? &gobject_ : 0; }
+
+  bool get_is_end_() const
+  {
+    return is_end_;
+  }
+
+  //This is only used by the iterator template internally.
+  TreeModel* get_model_()
+  {
+    return model_;
+  }
+
+  const TreeModel* get_model_() const
+  {
+    return model_;
+  }
+    
+#endif //DOXYGEN_SHOULD_SKIP_THIS
+
+protected:
+  //Utility functions used by the derived templated iterator
+  //so we can keep the implementation out of the header:
+  void iter_next();
+  void iter_previous();
+
+  GtkTreeIter gobject_;
+
+  // Yes, using a simple TreeModel* rather than Glib::RefPtr<TreeModel>
+  // violates the general policy.  But Gtk::TreeIter should have a trivial
+  // copy constructor and assignment operator, i.e. it must contain only
+  // POD (plain old data).
+  //
+  // Gtk::TreeIter is copied a lot, particularly often as return value from
+  // methods.  Postfix ++ must return by value, and STL algorithms usually
+  // pass iterators by value, too.  With a RefPtr<> as member data, copying
+  // would no longer be trivial, and even cause frequent calls to reference()
+  // and unreference().  That usually doesn't matter much for GUI stuff, but
+  // Gtk::TreeModel is used as a generic container.  Imagine a for-loop that
+  // checks whether iter != children.end() on each iteration.
+
+  
+  TreeModel* model_;
+  bool       is_end_;
+
+  friend class Gtk::TreeRow<TreeRow, TreeRow&, TreeRow*>;
+  friend class Gtk::TreeRow<TreeRow, const TreeRow&, const TreeRow*>;
+  
+  friend class Gtk::TreeNodeChildren<TreeRow, TreeRow&, TreeRow*>;
+  friend class Gtk::TreeNodeChildren<TreeRow, const TreeRow&, const TreeRow*>;
+  
+  friend class Gtk::TreeModel;
 };
 
 
@@ -94,101 +211,168 @@ class TreeIterBase
  * The Gtk::TreeModel iterator.
  * @ingroup TreeView
  */
+template<class _Tp, class _Ref, class _Ptr>
 class TreeIter : public TreeIterBase
 {
 public:
+  //These are like the typedefs found in /usr/include/g++3/stl_list.h, in _List_Iterator:
+
+  //Note that iterator here is usually the same as TreeModel::iterator, even if this a const_iterator:
+  typedef TreeIter<_Tp, _Tp&, _Tp*>             iterator;
+  typedef TreeIter<_Tp, const _Tp&, const _Tp*> const_iterator;
+  typedef TreeIter<_Tp, _Ref, _Ptr>             _Self;
+  
   typedef std::bidirectional_iterator_tag iterator_category;
-  typedef Gtk::TreeRow              value_type;
-  typedef int                       difference_type;
-  typedef const Gtk::TreeRow&       reference;
-  typedef const Gtk::TreeRow*       pointer;
+  typedef _Tp value_type;
+  typedef int difference_type;
+  typedef _Ref reference;
+  typedef _Ptr pointer;
+
+  TreeIter()
+  : TreeIterBase()
+  {}
+
+  //Allow a conversion from iterator to const_iterator,
+  //and from iterator to iterator:
+  TreeIter(const iterator& src)
+  : TreeIterBase()
+  {
+    const GtkTreeIter* cIter = src.gobj();
+    gobject_ = *cIter;
+    model_ = const_cast<Gtk::TreeModel*>(src.get_model_());
+    is_end_ = src.get_is_end_();
+  }
+
+  //Allow a conversion from iterator to const_iterator,
+  TreeIter& operator=(const iterator& src)
+  {
+    if(this == &src)
+      return *this;
+
+    gobject_ = *(src.gobj());
+    model_ = const_cast<Gtk::TreeModel*>(src.get_model_());
+    is_end_ = src.get_is_end_();
+
+    return *this;
+  }
+
+  operator bool() const
+  {
+    if(is_end_)
+      return false;
+
+    if(model_)
+      return model_->iter_is_valid(*this);
+    else
+    {
+      g_warning("Gtk::TreeIterBase::operator bool(): defaulting to false because this iterator has no TreeModel.");
+      return false; //This should never happen, but let's not segfault if it does.
+    }
+
+    //This is what we did before we had the iter_is_valid() method:
+    //we still use it in the default implementation of TreeModel::iter_is_valid().
+    //
+    // Test whether the GtkTreeIter is valid and not an end iterator.  This check
+    // is almost the same as the private VALID_ITER() macro in gtkliststore.c and
+    // gtktreestore.c.
+    //return (!is_end_ && gobject_.stamp != 0);
+  }
+
+  TreeIter& operator++()
+  {
+    iter_next();
+
+    return *this;
+  }
+
+  _Self operator++(int)
+  {
+    TreeIter previous(*this);
 
-  TreeIter();
+    iter_next();
 
-  TreeIter&      operator++();
-  const TreeIter operator++(int);
+    return previous;
+  }
 
   /** Please note that this is slow compared to operator++().
    */
-  TreeIter&      operator--();
+  _Self& operator--()
+  {
+    iter_previous();
 
-  /** Please note that this is slow compared to operator++().
-   */
-  const TreeIter operator--(int);
-  
-  inline reference operator*()  const;
-  inline pointer   operator->() const;
-
-  bool equal(const TreeIter& other) const;
-
-  /** Discover whether the iterator is valid, and not equal to end().
-   */
-  operator bool() const;
-
-  /** This is only useful when implementing a custom Gtk::TreeModel class.
-   * Compare the iterator's stamp with your model's stamp to discover whether it is valid.
-   * @see set_stamp().
-   * @result The iterator's stamp.
-   */
-  int get_stamp() const;
+    return *this;
+  }
 
-  /** This is only useful when implementing a custom Gtk::TreeModel class.
-   * Set the stamp to be equal to your model's stamp, to mark the iterator as valid.
-   * When your model's structure changes, you should increment your model's stamp
-   * to mark all older iterators as invalid. They will be recognised as invalid because
-   * they will then have an incorrect stamp.
+  /** Please note that this is slow compared to operator++().
    */
-  void set_stamp(int stamp);
+  _Self operator--(int)
+  {
+    TreeIter previous(*this);
+
+    iter_previous();
+
+    return previous;
+  }
+
+  inline reference operator*() const
+  {
+    //We const_cast<> because the non-const iterator should be able to return a non-const reference from this const method.
+    //Well, anyway, that's what _List_iterator does in the g++ header. murrayc.
+    return static_cast<reference>(const_cast<_Self&>(*this));
+  }
+
+  inline pointer operator->() const
+  {
+    //We const_cast<> because the non-const iterator should be able to return a non-const reference from this const method.
+    //Well, anyway, that's what _List_iterator does in the g++ header. murrayc.
+    return static_cast<pointer>(const_cast<_Self*>(this));
+  }
+
+  bool equal(const _Self& other) const
+  {
+    //There is no public gtk_tree_iter_equal(), so we must write our own.
+
+    g_assert(model_ == other.model_);
+
+    // A GtkTreeIter has the same stamp value as its model.
+    g_assert(gobject_.stamp == other.gobject_.stamp || is_end_ || other.is_end_);
+
+    // If all user_data pointers are equal we can assume the iterators to be
+    // equal.  This should be safe since GtkTreeIter lacks destroy notification,
+    // thus there is no way to attach more data fields to the iterator.
+    return (is_end_ == other.is_end_) &&
+           (gobject_.user_data  == other.gobject_.user_data)  &&
+           (gobject_.user_data2 == other.gobject_.user_data2) &&
+           (gobject_.user_data3 == other.gobject_.user_data3);
+  }
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-  explicit TreeIter(TreeModel* model); // used in TreeModel methods
-  TreeIter(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
+  explicit TreeIter(TreeModel* model) // used in TreeModel methods
+  : TreeIterBase()
+  {
+    model_ = model;
+  }
+
+  TreeIter(GtkTreeModel* model, const GtkTreeIter* iter) // used by signal proxies
+  : TreeIterBase(iter)
+  {
+    model_ = dynamic_cast<TreeModel*>( Glib::wrap_auto((GObject*)model) );
+  }
 
-  void set_model_refptr(const Glib::RefPtr<TreeModel>& model);
-  void set_model_gobject(GtkTreeModel* model);
-  GtkTreeModel* get_model_gobject() const;
-
-  void setup_end_iterator(const TreeIter& last_valid);
-
-  const GtkTreeIter* get_gobject_if_not_end() const
-    { return (!is_end_) ? &gobject_ : 0; }
-
-  const GtkTreeIter* get_parent_gobject_if_end() const
-    { return (is_end_ && gobject_.stamp) ? &gobject_ : 0; }
+  #endif // DOXYGEN_SHOULD_SKIP_THIS
 
-protected:
-
-  // Yes, using a simple TreeModel* rather than Glib::RefPtr<TreeModel>
-  // violates the general policy.  But Gtk::TreeIter should have a trivial
-  // copy constructor and assignment operator, i.e. it must contain only
-  // POD (plain old data).
-  //
-  // Gtk::TreeIter is copied a lot, particularly often as return value from
-  // methods.  Postfix ++ must return by value, and STL algorithms usually
-  // pass iterators by value, too.  With a RefPtr<> as member data, copying
-  // would no longer be trivial, and even cause frequent calls to reference()
-  // and unreference().  That usually doesn't matter much for GUI stuff, but
-  // Gtk::TreeModel is used as a generic container.  Imagine a for-loop that
-  // checks whether iter != children.end() on each iteration.
-
-  TreeModel* model_;
-  bool       is_end_;
-
-  friend class Gtk::TreeRow;
-  friend class Gtk::TreeNodeChildren;
-  friend class Gtk::TreeModel;
-
-#endif // DOXYGEN_SHOULD_SKIP_THIS
 };
 
 /** @relates Gtk::TreeIter */
-inline bool operator==(const TreeIter& lhs, const TreeIter& rhs)
-  { return lhs.equal(rhs); }
+template<class _Tp, class _Ref, class _Ptr>
+inline bool operator==(const TreeIter<_Tp, _Ref, _Ptr>& lhs, const TreeIter<_Tp, _Ref, _Ptr>& rhs)
+    { return lhs.equal(rhs); }
 
 /** @relates Gtk::TreeIter */
-inline bool operator!=(const TreeIter& lhs, const TreeIter& rhs)
-  { return !lhs.equal(rhs); }
+template<class _Tp, class _Ref, class _Ptr>
+inline bool operator!=(const TreeIter<_Tp, _Ref, _Ptr>& lhs, const TreeIter<_Tp, _Ref, _Ptr>& rhs)
+    { return !lhs.equal(rhs); }
 
 
 template <class ColumnType>
@@ -222,9 +406,18 @@ private:
  * You can use a const TreeModel::Row& for any parameter that takes a const TreeModel::iterator&.
  * @ingroup TreeView
  */
-class TreeRow : public TreeIter //We use public inheritance so that we can cast from a TreeRow to a TreeIter.
+template<class _Tp, class _Ref, class _Ptr>
+class TreeRow : public TreeIter<_Tp, _Ref, _Ptr*>
 {
+  // We use public inheritance so that we can cast from a TreeRow to a TreeIter.
+  // And so that we can return a TreeRow pointer or reference from TreeIter::operator* and TreeIter::operator->,
+  // by casting, without complicated memory management.
+  // TODO: Alternatives?: Have a TreeRow instance in every TreeIter instance? That would be slow. murrayc.
+  
 public:
+   typedef TreeIter<_Tp, _Ref, _Ptr> iterator;
+   typedef TreeIter<_Tp, const _Tp&, const _Tp*> const_iterator;
+   typedef iterator _Base;
 
   /** Use this to set and get the value of this @a column of this row.
    * This is a templated method, so the compiler will not allow you to provide an inappropriate type
@@ -285,19 +478,24 @@ public:
   const TreeNodeChildren& children() const;
 
   /** Gets an iterator to the parent row of this row.
-   * @result An itereator to the parent row.
+   * @result An iterator to the parent row.
    */
-  TreeIter parent() const;
+  iterator parent();
+
+  /** Gets an iterator to the parent row of this row.
+   * @result An iterator to the parent row.
+   */
+  const_iterator parent() const;
 
   /** Discover whether this is a valid row.
    */
   operator bool() const;
 
-  /// Provides access to the underlying C GObject.  
-  GtkTreeIter*       gobj()       { return TreeIter::gobj(); }
+  /// Provides access to the underlying C GObject.
+  GtkTreeIter*       gobj()       { return _Base::gobj(); }
 
-  /// Provides access to the underlying C GObject.  
-  const GtkTreeIter* gobj() const { return TreeIter::gobj(); }
+  /// Provides access to the underlying C GObject.
+  const GtkTreeIter* gobj() const { return _Base::gobj(); }
 
 private:
   // Forwarders to Gtk::TreeModel virtual methods.
@@ -312,17 +510,20 @@ private:
  * Virtual container of TreeModel::Row items.
  * @ingroup TreeView
  */
-class TreeNodeChildren : public TreeIter
+template<class _Tp, class _Ref, class _Ptr>
+class TreeNodeChildren : public TreeIter<_Tp, _Ref, _Ptr>
 {
 public:
-  typedef Gtk::TreeRow  value_type;
+  typedef Gtk::TreeRow<_Tp, _Ref, _Ptr>  value_type;
   typedef unsigned int  size_type;
   typedef int           difference_type;
-  typedef Gtk::TreeIter iterator;
+  typedef TreeIter<_Tp, _Ref, _Ptr> iterator;
+  typedef TreeIter<_Tp, const _Tp&, const _Ptr*> const_iterator;
   typedef std::reverse_iterator<iterator> reverse_iterator;
-  typedef Gtk::TreeIter const_iterator; //TODO: Make it a real const_iterator.
   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
+  typedef iterator _Base;
+
   iterator begin();
   const_iterator begin() const;
   iterator end();
@@ -341,10 +542,13 @@ public:
   bool empty() const;
   operator bool() const { return !empty(); }
 
+  iterator get_iterator();
+  const_iterator get_iterator() const;
+  
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
   explicit TreeNodeChildren(TreeModel* model)
-    : TreeIter(model) {}
+    : _Base(model) {}
 
   const GtkTreeIter* get_parent_gobject() const
     { return (gobject_.stamp != 0) ? &gobject_ : 0; }
@@ -355,20 +559,6 @@ public:
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-/**** Gtk::TreeIter ********************************************************/
-
-inline
-TreeIter::reference TreeIter::operator*() const
-{
-  return static_cast<const TreeRow&>(*this);
-}
-
-inline
-TreeIter::pointer TreeIter::operator->() const
-{
-  return static_cast<const TreeRow*>(this);
-}
-
 
 /**** Gtk::TreeValueProxy<> ************************************************/
 
Index: gtk/src/treemodel.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treemodel.ccg,v
retrieving revision 1.4
diff -u -p -r1.4 treemodel.ccg
--- gtk/src/treemodel.ccg	16 Jan 2004 13:48:18 -0000	1.4
+++ gtk/src/treemodel.ccg	29 Feb 2004 16:33:55 -0000
@@ -143,7 +143,7 @@ void TreeModel::foreach(const SlotForeac
   gtk_tree_model_foreach(gobj(), &proxy_foreach_path_and_iter_callback, &slot_copy);
 }
 
-bool TreeModel::iter_is_valid(const iterator& iter) const
+bool TreeModel::iter_is_valid(const const_iterator& iter) const
 {
   //This method is overriden in TreeStore and ListStore.
   //This implementation will only be used as a default for custom derived TreeModels,
Index: gtk/src/treemodel.hg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treemodel.hg,v
retrieving revision 1.13
diff -u -p -r1.13 treemodel.hg
--- gtk/src/treemodel.hg	26 Feb 2004 22:28:25 -0000	1.13
+++ gtk/src/treemodel.hg	29 Feb 2004 16:33:55 -0000
@@ -32,6 +32,17 @@ class TreeModelSort;
 class TreePath;
 class TreeRowReference;
 
+class TreeIterBase;
+
+template<class _Tp, class _Ref, class _Ptr>
+class TreeIter;
+
+template<class _Tp, class _Ref, class _Ptr>
+class TreeRow;
+
+template<class _Tp, class _Ref, class _Ptr>
+class TreeNodeChildren;
+
 _CC_INCLUDE(gtk/gtktypebuiltins.h)
 _WRAP_ENUM(TreeModelFlags, GtkTreeModelFlags)
 
@@ -94,13 +105,13 @@ class TreeModel : public Glib::Interface
 public:
   typedef TreeModelColumnRecord ColumnRecord;
 
-  typedef TreeNodeChildren Children;
+  typedef TreeNodeChildren<TreeRow, TreeRow&, TreeRow*> Children;
   typedef Children::iterator iterator;
   typedef Children::reverse_iterator reverse_iterator;
   typedef Children::const_iterator const_iterator;
   typedef Children::const_reverse_iterator const_reverse_iterator;
   
-  typedef TreeRow Row;
+  typedef Children::value_type Row;
   typedef TreePath Path;
   typedef TreeRowReference RowReference;
   
@@ -377,7 +388,7 @@ dnl
    *
    * @result true if the iterator is valid.
    */
-  virtual bool iter_is_valid(const iterator& iter) const;
+  virtual bool iter_is_valid(const const_iterator& iter) const;
 
   //Called by TreeRow, which is a friend class:
   //The comment about set_row_changed() in the documentation is based on my reading of the source of
@@ -394,7 +405,8 @@ dnl
 
   friend class Gtk::TreeModelSort;
   friend class Gtk::TreeRow;
-  friend class Gtk::TreeIter;
+  friend class iterator;
+  friend class const_iterator;
 };
 
 } // namespace Gtk
Index: gtk/src/treemodelfilter.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treemodelfilter.ccg,v
retrieving revision 1.5
diff -u -p -r1.5 treemodelfilter.ccg
--- gtk/src/treemodelfilter.ccg	26 Feb 2004 22:59:50 -0000	1.5
+++ gtk/src/treemodelfilter.ccg	29 Feb 2004 16:33:55 -0000
@@ -18,6 +18,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <gtkmm/treeiter.h>
 #include <gtk/gtktreemodelfilter.h>
 
 namespace //anonymous
@@ -101,7 +102,7 @@ void SignalProxy_Modify::gtk_callback(Gt
     GType column_type = gtk_tree_model_get_column_type(model, column);
     cppValue.init(column_type);
     
-    return (self->slot_)( Gtk::TreeModel::const_iterator(model, iter), cppValue, column );
+    return (self->slot_)( Gtk::TreeModel::iterator(model, iter), cppValue, column );
 
     g_value_init(value, column_type);
 
@@ -144,7 +145,7 @@ void TreeModelFilter::set_visible_func(c
 
 TreeModel::iterator TreeModelFilter::convert_child_iter_to_iter(const iterator& child_iter) const
 {
-  TreeIter filter_iter (const_cast<TreeModelFilter*>(this));
+  iterator filter_iter (const_cast<TreeModelFilter*>(this));
 
   gtk_tree_model_filter_convert_child_iter_to_iter(
       const_cast<GtkTreeModelFilter*>(gobj()), filter_iter.gobj(),
@@ -157,7 +158,7 @@ TreeModel::iterator TreeModelFilter::con
 {
   GtkTreeModel *const child_model = gtk_tree_model_filter_get_model(const_cast<GtkTreeModelFilter*>(gobj()));
 
-  TreeIter child_iter (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
+  iterator child_iter (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
 
   gtk_tree_model_filter_convert_iter_to_child_iter(
       const_cast<GtkTreeModelFilter*>(gobj()), child_iter.gobj(),
Index: gtk/src/treemodelsort.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treemodelsort.ccg,v
retrieving revision 1.2
diff -u -p -r1.2 treemodelsort.ccg
--- gtk/src/treemodelsort.ccg	4 Nov 2003 18:11:36 -0000	1.2
+++ gtk/src/treemodelsort.ccg	29 Feb 2004 16:33:55 -0000
@@ -18,6 +18,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <gtkmm/treeiter.h>
 #include <gtk/gtktreemodelsort.h>
 
 
@@ -28,7 +29,7 @@ namespace Gtk
 
 TreeModel::iterator TreeModelSort::convert_child_iter_to_iter(const iterator& child_iter) const
 {
-  TreeIter sorted_iter (const_cast<TreeModelSort*>(this));
+  iterator sorted_iter (const_cast<TreeModelSort*>(this));
 
   gtk_tree_model_sort_convert_child_iter_to_iter(
       const_cast<GtkTreeModelSort*>(gobj()), sorted_iter.gobj(),
@@ -41,7 +42,7 @@ TreeModel::iterator TreeModelSort::conve
 {
   GtkTreeModel *const child_model = gtk_tree_model_sort_get_model(const_cast<GtkTreeModelSort*>(gobj()));
 
-  TreeIter child_iter (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
+  iterator child_iter (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
 
   gtk_tree_model_sort_convert_iter_to_child_iter(
       const_cast<GtkTreeModelSort*>(gobj()), child_iter.gobj(),
@@ -58,7 +59,7 @@ void TreeModelSort::set_value_impl(const
   TreeModel *const child_model = dynamic_cast<TreeModel*>(
       Glib::wrap_auto((GObject*) gtk_tree_model_sort_get_model(gobj()), false));
 
-  TreeIter child_iter (child_model);
+  iterator child_iter (child_model);
 
   gtk_tree_model_sort_convert_iter_to_child_iter(
       gobj(), child_iter.gobj(), const_cast<GtkTreeIter*>(row.gobj()));
Index: gtk/src/treemodelsort.hg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treemodelsort.hg,v
retrieving revision 1.3
diff -u -p -r1.3 treemodelsort.hg
--- gtk/src/treemodelsort.hg	5 Jan 2004 17:32:17 -0000	1.3
+++ gtk/src/treemodelsort.hg	29 Feb 2004 16:33:55 -0000
@@ -69,7 +69,7 @@ public:
   _WRAP_METHOD(void reset_default_sort_func(), gtk_tree_model_sort_reset_default_sort_func)
   _WRAP_METHOD(void clear_cache(), gtk_tree_model_sort_clear_cache)
 
-  _WRAP_METHOD(bool iter_is_valid(const iterator& iter) const, gtk_tree_model_sort_iter_is_valid)
+  _WRAP_METHOD(bool iter_is_valid(const const_iterator& iter) const, gtk_tree_model_sort_iter_is_valid)
 
 protected:
   virtual void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value);
Index: gtk/src/treepath.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treepath.ccg,v
retrieving revision 1.4
diff -u -p -r1.4 treepath.ccg
--- gtk/src/treepath.ccg	3 Nov 2003 09:29:59 -0000	1.4
+++ gtk/src/treepath.ccg	29 Feb 2004 16:33:55 -0000
@@ -18,6 +18,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <gtkmm/treeiter.h>
 #include <gtkmm/treemodel.h>
 #include <glibmm/utility.h>
 #include <gtk/gtktreemodel.h>
Index: gtk/src/treesortable.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treesortable.ccg,v
retrieving revision 1.4
diff -u -p -r1.4 treesortable.ccg
--- gtk/src/treesortable.ccg	26 Feb 2004 22:59:50 -0000	1.4
+++ gtk/src/treesortable.ccg	29 Feb 2004 16:33:55 -0000
@@ -52,7 +52,7 @@ int SignalProxy_Compare::gtk_callback(Gt
   try
   {
     // use Slot::operator()
-    return (self->slot_)(Gtk::TreeIter(model, lhs), Gtk::TreeIter(model, rhs));
+    return (self->slot_)(Gtk::TreeModel::iterator(model, lhs), Gtk::TreeModel::iterator(model, rhs));
   }
   catch(...)
   {
Index: gtk/src/treestore.hg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treestore.hg,v
retrieving revision 1.3
diff -u -p -r1.3 treestore.hg
--- gtk/src/treestore.hg	20 Jan 2004 17:48:10 -0000	1.3
+++ gtk/src/treestore.hg	29 Feb 2004 16:33:55 -0000
@@ -143,7 +143,7 @@ public:
   _WRAP_METHOD(bool is_ancestor(const iterator& iter, const iterator& descendant) const, gtk_tree_store_is_ancestor)
   _WRAP_METHOD(int iter_depth(const iterator& iter) const, gtk_tree_store_iter_depth)
 
-  _WRAP_METHOD(bool iter_is_valid(const iterator& iter) const, gtk_tree_store_iter_is_valid)
+  _WRAP_METHOD(bool iter_is_valid(const const_iterator& iter) const, gtk_tree_store_iter_is_valid)
 
 protected:
   virtual void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value);
Index: gtk/src/treeview.ccg
===================================================================
RCS file: /cvs/gnome/gtkmm/gtk/src/treeview.ccg,v
retrieving revision 1.5
diff -u -p -r1.5 treeview.ccg
--- gtk/src/treeview.ccg	26 Feb 2004 22:59:50 -0000	1.5
+++ gtk/src/treeview.ccg	29 Feb 2004 16:33:55 -0000
@@ -108,7 +108,7 @@ gboolean SignalProxy_SearchEqual::gtk_ca
 
   try
   {
-    return (self->slot_)(Glib::wrap(model, true), column, key, Gtk::TreeIter(model, iter));
+    return (self->slot_)(Glib::wrap(model, true), column, key, Gtk::TreeModel::iterator(model, iter));
   }
   catch(...)
   {
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/gnome/gtkmm/tests/Makefile.am,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile.am
--- tests/Makefile.am	25 Oct 2003 15:21:14 -0000	1.4
+++ tests/Makefile.am	29 Feb 2004 16:33:56 -0000
@@ -1,7 +1,7 @@
 test_dirs = child_widget child_widget2 child_widget_managed \
             refcount_dialog dialog dialog_deletethis delete_cpp_child \
             menu_destruction \
-            scrolledwindow wrap_existing
+            scrolledwindow treemodel_const_iterator wrap_existing
 
 SUBDIRS = $(test_dirs)
 EXTRA_DIST = Makefile.am_fragment
Index: tools/m4/convert_gtk.m4
===================================================================
RCS file: /cvs/gnome/gtkmm/tools/m4/convert_gtk.m4,v
retrieving revision 1.22
diff -u -p -r1.22 convert_gtk.m4
--- tools/m4/convert_gtk.m4	26 Feb 2004 22:28:30 -0000	1.22
+++ tools/m4/convert_gtk.m4	29 Feb 2004 16:33:56 -0000
@@ -378,6 +378,7 @@ _CONVERSION(`const TreeModel::Row&',`Gtk
 _CONVERSION(`iterator&',`GtkTreeIter*',__FR2P)
 _CONVERSION(`const TreeModel::iterator&',`GtkTreeIter*',__FCR2P)
 _CONVERSION(`const iterator&',`GtkTreeIter*',__FCR2P)
+_CONVERSION(`const const_iterator&',`GtkTreeIter*',__FCR2P)
 _CONVERSION(`TreeViewColumn&',`GtkTreeViewColumn*',__FR2P)
 _CONVERSION(`GtkTreeViewColumn*',`TreeViewColumn*',`Glib::wrap($3)')
 _CONVERSION(`GtkTreeViewColumn*',`const TreeViewColumn*',`Glib::wrap($3)')
