Index: ChangeLog
===================================================================
--- ChangeLog	(revision 723)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2008-08-26  Szilárd Pfeiffer  <szilard.pfeiffer@gmail.com>
+
+	* glib/src/nodetree.hg: Implemented clone function to merge the
+	constructors into that and fixed clear function the operator=
+	function.
+	* tests/glibmm_nodetree/main.cc: Simplified the test case.
+	Bug #547901.
+
 2008-08-27  Armin Burgmeier  <armin@arbur.net>
 
 	* MSVC_Net2005/glibmm/glibmm.rc.in:
Index: tests/glibmm_nodetree/main.cc
===================================================================
--- tests/glibmm_nodetree/main.cc	(revision 723)
+++ tests/glibmm_nodetree/main.cc	(working copy)
@@ -1,7 +1,7 @@
 #include <iostream>
 #include <glibmm.h>
 
-typedef Glib::NodeTree<std::string> type_nodetree_string;
+typedef Glib::NodeTree<const std::string> type_nodetree_string;
 
 static bool node_build_string(type_nodetree_string& node, std::string& string)
 {
@@ -21,41 +21,29 @@
   type_nodetree_string* node_F;
   type_nodetree_string* node_G;
   type_nodetree_string* node_J;
-  std::string str_A("A");
-  std::string str_B("B");
-  std::string str_C("C");
-  std::string str_D("D");
-  std::string str_E("E");
-  std::string str_F("F");
-  std::string str_G("G");
-  std::string str_H("H");
-  std::string str_I("I");
-  std::string str_J("J");
-  std::string str_K("K");
-  std::string str_empty;
 
-  root = new type_nodetree_string(str_A);
+  root = new type_nodetree_string("A");
   g_assert(root->depth() == 1 && root->get_max_height() == 1);
 
-  node_B = new type_nodetree_string(str_B);
+  node_B = new type_nodetree_string("B");
   root->append(*node_B);
   g_assert(root->first_child() == node_B);
 
-  node_B->append_data(str_E);
-  node_B->prepend_data(str_C);
-  node_D = &node_B->insert(1, *(new type_nodetree_string(str_D)));
+  node_B->append_data("E");
+  node_B->prepend_data("C");
+  node_D = &node_B->insert(1, *(new type_nodetree_string("D")));
 
-  node_F = new type_nodetree_string(str_F);
+  node_F = new type_nodetree_string("F");
   root->append(*node_F);
   g_assert(root->first_child()->next_sibling() == node_F);
 
-  node_G = new type_nodetree_string(str_G);
+  node_G = new type_nodetree_string("G");
   node_F->append(*node_G);
-  node_J = new type_nodetree_string(str_J);
+  node_J = new type_nodetree_string("J");
   node_G->prepend(*node_J);
-  node_G->insert(42, *(new type_nodetree_string(str_K)));
-  node_G->insert_data(0, str_H);
-  node_G->insert(1, *(new type_nodetree_string(str_I)));
+  node_G->insert(42, *(new type_nodetree_string("K")));
+  node_G->insert_data(0, "H");
+  node_G->insert(1, *(new type_nodetree_string("I")));
 
   g_assert(root->depth() == 1);
   g_assert(root->get_max_height() == 4);
@@ -65,9 +53,9 @@
   g_assert(root->node_count(type_nodetree_string::TRAVERSE_ALL) == 11);
   g_assert(node_F->get_max_height() == 3);
   g_assert(node_G->child_count() == 4);
-  g_assert(root->find_child(str_F, type_nodetree_string::TRAVERSE_ALL) == node_F);
-  g_assert(root->find(str_I, Glib::TRAVERSE_LEVEL_ORDER, type_nodetree_string::TRAVERSE_NON_LEAVES) == NULL);
-  g_assert(root->find(str_J, Glib::TRAVERSE_IN_ORDER, type_nodetree_string::TRAVERSE_LEAVES) == node_J);
+  g_assert(root->find_child("F", type_nodetree_string::TRAVERSE_ALL) == node_F);
+  g_assert(root->find("I", Glib::TRAVERSE_LEVEL_ORDER, type_nodetree_string::TRAVERSE_NON_LEAVES) == NULL);
+  g_assert(root->find("J", Glib::TRAVERSE_IN_ORDER, type_nodetree_string::TRAVERSE_LEAVES) == node_J);
 
   for(guint i = 0; i < node_B->child_count(); i++)
     {
@@ -132,12 +120,12 @@
 
   /* allocation tests */
 
-  root = new type_nodetree_string(str_empty);
+  root = new type_nodetree_string();
   node = root;
 
   for(guint i = 0; i < 2048; i++)
     {
-      node->append(*(new type_nodetree_string(str_empty)));
+      node->append(*(new type_nodetree_string()));
       if((i % 5) == 4)
         node = node->first_child()->next_sibling();
     }
Index: glib/src/nodetree.hg
===================================================================
--- glib/src/nodetree.hg	(revision 723)
+++ glib/src/nodetree.hg	(working copy)
@@ -83,47 +83,43 @@
   }
 
 public:
+  NodeTree()
+  {
+    clone();
+  }
+
   explicit NodeTree(const T& data) :
     data_(data)
   {
-    //Store the this pointer in the GNode so we can discover this wrapper later:
-    gobject_ = g_node_new(reinterpret_cast<gpointer>(this));
+    clone();
   }
   _IGNORE(g_node_new)
 
+  NodeTree(const NodeTree<T>& node) :
+    data_(node.data())
+  {
+    clone(&node);
+  }
+
   /** Removes the instance and its children from the tree,
    * freeing any memory allocated.
    */
   ~NodeTree()
   {
+    if(!is_root())
+      unlink();
+
     clear();
   }
   _IGNORE(g_node_destroy)
 
-  NodeTree(const NodeTree<T>& node) :
-    data_(node.data_)
-  {
-    //Store the this pointer in the GNode so we can discover the wrapped object later.
-    gobject_ = g_node_new(reinterpret_cast<gpointer>(this));
-
-    //Prepend the copied children of @node to the constructing node.
-    for(const NodeTree<T>* i = node.last_child();  i != 0; i = i->prev_sibling())
-      prepend(*(new NodeTree<T>(*i)));
-  }
-
   NodeTree<T>& operator=(const NodeTree<T>& node)
   {
     clear();
+    clone(&node);
 
-    //Do the same as the copy constructor:
+    data_ = node.data();
 
-    //Store the this pointer in the GNode so we can discover the wrapped object later.
-    gobject_ = g_node_new(reinterpret_cast<gpointer>(this));
-
-    //Prepend the copied children of @node to the constructing node.
-    for(const NodeTree<T>* i = node.last_child();  i != 0; i = i->prev_sibling())
-      prepend(*(new NodeTree<T>(*i)));
-
     return *this;
   }
 
@@ -684,24 +680,30 @@
 
 private:
 
-  ///Delete all the underlying objects and data.
   void clear()
   {
-    if(!gobject_)
-      return;
-
-    if(!is_root())
-      unlink();
-
     //Free the children (not just with g_node_destroy(), to avoid the leaking of C++ wrapper objects):
     while(NodeTree<T>* i = first_child())
       delete i;
 
-    //Free the wrapped object:
+    //Free the wrapped object (g_node_free not available)
     g_slice_free(GNode, gobject_);
+    gobject_ = 0;
   }
 
+  void clone(const NodeTree<T> *node = 0)
+  {
+    //Store the this pointer in the GNode so we can discover this wrapper later:
+    gobject_ = g_node_new(reinterpret_cast<gpointer>(this));
 
+    if(node)
+    {
+      //Prepend the copied children of @node to the constructing node.
+      for(const NodeTree<T>* i = node->last_child();  i != 0; i = i->prev_sibling())
+        prepend(*(new NodeTree<T>(*i)));
+    }
+  }
+
   /// Wrapper for invoking a TraverseFunc.
   static gboolean c_callback_traverse(GNode* node, gpointer slot)
   {
