Fix crash on startup if an LV2 plugin has a bad .ttl file.
[ardour.git] / libs / glibmm2 / glib / src / nodetree.hg
1 /* Copyright (C) 2007 glibmm development team
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Library General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Library General Public License for more details.
12  *
13  * You should have received a copy of the GNU Library General Public
14  * License along with this library; if not, write to the Free
15  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16  */
17
18 _DEFS(glibmm,glib)
19
20 #include <map>
21 #include <stack>
22 #include <deque>
23
24 #include <glibmm/refptr.h>
25 #include <glibmm/ustring.h>
26 #include <glibmm/error.h>
27 #include <glibmm/arrayhandle.h>
28 #include <glib.h>
29
30 namespace Glib
31 {
32
33 //Hand-written, instead of using _WRAP_ENUM, 
34 //because the C enum values don't have a prefix.
35
36 /** Specifies the type of traveral performed by methods such as NodeTree::_traverse() and NodeTree::find().
37  * 
38  * @ingroup glibmmEnums
39  */
40 enum TraverseType
41 {
42   TRAVERSE_IN_ORDER = G_IN_ORDER, /*!< Visits a node's left child first, then the node itself, then its right child. This is the one to use if you want the output sorted according to the compare function.  */
43   TRAVERSE_PRE_ORDER = G_PRE_ORDER, /*!< Visits a node, then its children. */
44   TRAVERSE_POST_ORDER = G_POST_ORDER, /*!< Visits the node's children, then the node itself. */
45   TRAVERSE_LEVEL_ORDER = G_LEVEL_ORDER /*!< For NodeTree, it vists the root node first, then its children, then its grandchildren, and so on. Note that this is less efficient than the other orders. This is not implemented for Glib::Tree. */
46 };
47
48 /** N-ary Trees - trees of data with any number of branches
49  * The NodeTree class and its associated functions provide an N-ary tree data structure, in which nodes in the tree can contain arbitrary data.
50  * 
51  * To insert a node into a tree use insert(), insert_before(), append() or prepend().
52  * 
53  * To create a new node and insert it into a tree use insert_data(), insert_data_before(), append_data() and prepend_data().
54  * 
55  * To reverse the children of a node use reverse_children().
56  * 
57  * To find a node use root(), find(), find_child(), index_of(), child_index(), first_child(), last_child(), nth_child(), first_sibling(), prev_sibling(), next_sibling() or last_sibling().
58  * 
59  * To get information about a node or tree use is_leaf(), is_root(), depth(), node_count(), child_count(), is_ancestor() or max_height().
60  * 
61  * To traverse a tree, calling a function for each node visited in the traversal, use traverse() or foreach().
62  * 
63  * To remove a node or subtree from a tree use unlink().
64  *
65  * @newin2p18
66  */
67 template <typename T> 
68 class NodeTree
69 {
70   _CLASS_GENERIC(NodeTree, GNode)
71 public:
72   typedef sigc::slot<bool, NodeTree<T>&> TraverseFunc;
73   typedef sigc::slot<void, NodeTree<T>&> ForeachFunc;
74
75 private:
76   static NodeTree<T>* wrap(GNode* node)
77   {
78     if (!node)
79       return 0;
80
81     return reinterpret_cast<NodeTree<T>* >(node->data);
82   }
83
84 public:
85   NodeTree()
86   {
87     clone();
88   }
89
90   explicit NodeTree(const T& the_data) :
91     data_(the_data)
92   {
93     clone();
94   }
95   _IGNORE(g_node_new)
96
97   NodeTree(const NodeTree<T>& node) :
98     data_(node.data())
99   {
100     clone(&node);
101   }
102
103   /** Removes the instance and its children from the tree,
104    * freeing any memory allocated.
105    */
106   ~NodeTree()
107   {
108     if(!is_root())
109       unlink();
110
111     clear();
112   }
113   _IGNORE(g_node_destroy)
114
115   NodeTree<T>& operator=(const NodeTree<T>& node)
116   {
117     clear();
118     clone(&node);
119
120     data_ = node.data();
121
122     return *this;
123   }
124
125   /// Provides access to the underlying C GObject.
126   inline GNode* gobj()
127   {
128     return gobject_;
129   }
130
131   /// Provides access to the underlying C GObject.
132   inline const GNode* gobj() const
133   {
134     return gobject_;
135   }
136
137   /** Inserts a NodeTree beneath the parent at the given position.
138    *
139    * @param position the position to place node at, with respect to its siblings 
140    * If position is -1, node is inserted as the last child of parent
141    * @param node the NodeTree to insert
142    * @return the inserted NodeTree
143    */
144   NodeTree<T>& insert(int position, NodeTree<T>& node)
145   {
146     g_node_insert(gobj(), position, node.gobj());
147     return node;
148   }
149   _IGNORE(g_node_insert)
150
151   /** Inserts a NodeTree beneath the parent before the given sibling.
152    *
153    * @param sibling the sibling NodeTree to place node before.
154    * @param node the NodeTree to insert
155    * @return the inserted NodeTree
156    */
157   NodeTree<T>& insert_before(NodeTree<T>& sibling, NodeTree<T>& node)
158   {
159     g_node_insert_before(gobj(), sibling.gobj(), node.gobj());
160     return node;
161   }
162   _IGNORE(g_node_insert_before)
163
164   /** Inserts a NodeTree beneath the parent after the given sibling.
165    *
166    * @param sibling the sibling NodeTree to place node after.
167    * @param node the NodeTree to insert
168    * @return the inserted NodeTree
169    */
170   NodeTree<T>& insert_after(NodeTree<T>& sibling, NodeTree<T>& node)
171   {
172     g_node_insert_after(gobj(), sibling.gobj(), node.gobj());
173     return node;
174   }
175   _IGNORE(g_node_insert_after)
176
177
178   /** Inserts a NodeTree as the last child.
179    *
180    * @param node the NodeTree to append
181    * @return the new NodeTree
182    */
183   NodeTree<T>& append(NodeTree<T>& node)
184   {
185     g_node_append(gobj(), node.gobj());
186     return node;
187   }
188   _IGNORE(g_node_append)
189
190   /** Inserts a NodeTree as the first child.
191    *
192    * @param data the data for the NodeTree
193    * @return the NodeTree
194    */
195   NodeTree<T>& prepend(NodeTree<T>& node)
196   {
197     g_node_prepend(gobj(), node.gobj());
198     return node;
199   }
200   _IGNORE(g_node_prepend)
201
202   /** Inserts a new NodeTree at the given position.
203    *
204    * @param position the position to place the new NodeTree at. 
205    * If position is -1, the new NodeTree is inserted as the last child of parent
206    * @param data the data for the new NodeTree
207    * @return the new NodeTree
208    */
209   NodeTree<T>* insert_data(int position, const T& the_data)
210   {
211     NodeTree<T>* node = new NodeTree<T>(the_data);
212     insert(position, *node);
213     return node;
214   }
215   _IGNORE(g_node_insert_data)
216
217   /** Inserts a new NodeTree before the given sibling.
218    *
219    * @param sibling the sibling NodeTree to place node before. 
220    * @param data the data for the new NodeTree
221    * @return the new NodeTree
222    */
223   NodeTree<T>* insert_data_before(NodeTree<T>& sibling, const T& the_data)
224   {
225     NodeTree<T>* node = new NodeTree<T>(the_data);
226     insert_before(sibling, *node);
227     return node;
228   }
229   _IGNORE(g_node_insert_data_before)
230
231   /** Inserts a new NodeTree as the last child.
232    *
233    * @param data the data for the new NodeTree
234    * @return the new NodeTree
235    */
236   NodeTree<T>* append_data(const T& the_data)
237   {
238     NodeTree<T>* node = new NodeTree<T>(the_data);
239     append(*node);
240     return node;
241   }
242   _IGNORE(g_node_append_data)
243
244   /** Inserts a new NodeTree as the first child.
245    *
246    * @param data the data for the new NodeTree
247    * @return the new NodeTree
248    */
249   NodeTree<T>* prepend_data(const T& the_data)
250   {
251     NodeTree<T>* node = new NodeTree<T>(the_data);
252     prepend(*node);
253     return node;
254   }
255   _IGNORE(g_node_prepend_data)
256
257   /** Reverses the order of the children.
258    */
259   void reverse_children()
260   {
261     g_node_reverse_children(gobj());
262   }
263   _IGNORE(g_node_reverse_children)
264
265   /** Returns a pointer to the root of the tree.
266    *
267    * @return A pointer to the root of the tree.
268    */
269   NodeTree<T>* get_root()
270   {
271     return wrap(g_node_get_root(gobj()));
272   }
273
274   const NodeTree<T>* get_root() const
275   {
276     return wrap(g_node_get_root(gobj()));
277   }
278   _IGNORE(g_node_get_root)
279
280
281   /** Specifies which nodes are visited during several of the NodeTree methods,
282    *  including traverse() and find().
283    *
284    * @ingroup glibmmEnums
285    */
286   enum TraverseFlags
287   {
288     TRAVERSE_LEAVES = G_TRAVERSE_LEAVES, /*!< Only leaf nodes should be visited. */
289     TRAVERSE_NON_LEAVES = G_TRAVERSE_NON_LEAVES, /*!< Only non-leaf nodes should be visited. */
290     TRAVERSE_ALL = G_TRAVERSE_ALL, /*!< All nodes should be visited. */
291     TRAVERSE_MASK = G_TRAVERSE_MASK /*!< A mask of all traverse flags. */
292   };
293
294   /** Traverses a tree starting at the current node.
295    * It calls the given function for each node visited. 
296    * The traversal can be halted at any point by returning true from @a func.
297    *
298    * @param order The order in which nodes are visited.
299    * @param flags Which types of children are to be visited.
300    * @param max_depth The maximum depth of the traversal. 
301    * Nodes below this depth will not be visited. 
302    * If max_depth is -1 all nodes in the tree are visited.
303    * If max_depth is 1, only the root is visited.
304    * If max_depth is 2, the root and its children are visited. And so on.
305    * @param func the slot to invoke for each visited child
306    */
307   void traverse(const TraverseFunc& func, TraverseType order = TRAVERSE_IN_ORDER, TraverseFlags flags = TRAVERSE_ALL, int max_depth = -1)
308   {
309     TraverseFunc func_copy = func;
310     g_node_traverse(gobj(), (GTraverseType)order, (GTraverseFlags)flags, max_depth, c_callback_traverse, reinterpret_cast<gpointer>(&func_copy));
311   }
312   _IGNORE(g_node_traverse);
313
314   /** Calls a function for each of the children of a NodeTree.
315    * Note that it doesn't descend beneath the child nodes.
316    *
317    * @param flags Wwhich types of children are to be visited.
318    * @param func The slot to invoke for each visited node.
319    */
320   void foreach(const ForeachFunc& func, TraverseFlags flags = TRAVERSE_ALL)
321   {
322     ForeachFunc func_copy = func;
323     g_node_children_foreach(gobj(), (GTraverseFlags)flags, c_callback_foreach, reinterpret_cast<gpointer>(&func_copy));
324   }
325   _IGNORE(g_node_children_foreach)
326
327   /** Finds the first child of a NodeTree with the given data.
328    *
329    * @param flags Which types of children are to be visited, one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES.
330    * @param data The data for which to search.
331    * @return the found child, or 0 if the data is not found
332    */
333   NodeTree<T>* find_child(const T& the_data, TraverseFlags flags = TRAVERSE_ALL)
334   {
335     sigc::slot<void, GNode*, const T&, GNode**> real_slot = sigc::ptr_fun(on_compare_child);
336
337     GNode* child = 0;
338     typedef sigc::slot<void, GNode*> type_foreach_gnode_slot;
339     type_foreach_gnode_slot bound_slot = sigc::bind(real_slot, the_data, &child);
340
341     g_node_children_foreach(gobj(), (GTraverseFlags)flags, c_callback_foreach_compare_child, reinterpret_cast<gpointer>(&bound_slot));
342     
343     return wrap(child);
344   }
345
346   /** Finds the first child of a NodeTree with the given data.
347    *
348    * @param flags Which types of children are to be visited, one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES.
349    * @param data The data for which to search.
350    * @return the found child, or 0 if the data is not found
351    */
352   const NodeTree<T>* find_child(const T& the_data, TraverseFlags flags = TRAVERSE_ALL) const
353   {
354     return const_cast<NodeTree<T>*>(this)->find_child(flags, the_data);
355   }
356
357   _IGNORE(g_node_find_child)
358
359   /** Finds a node in a tree.
360    *
361    * @param order The order in which nodes are visited: IN_ORDER, TRAVERSE_PRE_ORDER, TRAVERSE_POST_ORDER, or TRAVERSE_LEVEL_ORDER
362    * @param flags Which types of children are to be visited: one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES.
363    * @param data The data for which to search.
364    * @return The found node, or 0 if the data is not found.
365    */
366   NodeTree<T>* find(const T& the_data, TraverseType order = TRAVERSE_IN_ORDER, TraverseFlags flags = TRAVERSE_ALL)
367   {
368     //We use a sigc::slot for the C callback, so we can bind some extra data.
369     sigc::slot<gboolean, GNode*, const T&, GNode**> real_slot = sigc::ptr_fun(on_compare_node);
370     GNode* child = 0;
371
372     typedef sigc::slot<gboolean, GNode*> type_traverse_gnode_slot;
373     type_traverse_gnode_slot bound_slot = sigc::bind(real_slot, the_data, &child);
374
375     g_node_traverse(const_cast<GNode*>(gobj()), (GTraverseType)order, (GTraverseFlags)flags, -1, c_callback_traverse_compare_node, reinterpret_cast<gpointer>(&bound_slot));
376
377     return wrap(child);
378   }
379
380   /** Finds a node in a tree.
381    *
382    * @param order The order in which nodes are visited.
383    * @param flags Which types of children are to be visited.
384    * @param data The data for which to search.
385    * @return The found node, or 0 if the data is not found.
386    */
387   const NodeTree<T>* find(const T& the_data, TraverseType order = TRAVERSE_IN_ORDER, TraverseFlags flags = TRAVERSE_ALL) const
388   {
389     return const_cast<NodeTree<T>*>(this)->find(order, flags, the_data);
390   }
391   _IGNORE(g_node_find)
392
393   /** Gets the position of the first child which contains the given data.
394    *
395    * @param data The data to find.
396    * @return The index of the child which contains data, or -1 if the data is not found.
397    */
398   int child_index(const T& the_data) const
399   {
400     int n = 0;
401
402     for(const NodeTree<T>* i = first_child();  i != 0; i = i->next_sibling())
403     {
404       if((i->data()) == the_data)
405         return n;
406
407       n++;
408     }
409
410     return -1;
411   }
412   _IGNORE(g_node_child_index)
413
414   /** Gets the position with respect to its siblings. 
415    * child must be a child of node.
416    * The first child is numbered 0, the second 1, and so on.
417    *
418    * @param child A child
419    * @return The position of @a child with respect to its siblings.
420    */
421   int child_position(const NodeTree<T>& child) const
422   {
423     return g_node_child_position(const_cast<GNode*>(gobj()), const_cast<GNode*>(child.gobj()));
424   }
425   _IGNORE(g_node_child_position)
426
427   /** Gets the first child.
428    *
429    * @return The first child, or 0 if the node has no children. 
430    */
431   NodeTree<T>* first_child()
432   {
433     return wrap(g_node_first_child(gobj()));
434   }
435
436   /** Gets the first child.
437    *
438    * @return The first child, or 0 if the node has no children. 
439    */
440   const NodeTree<T>* first_child() const
441   {
442     return const_cast<NodeTree<T>*>(this)->first_child();
443   }
444   _IGNORE(g_node_first_child)
445
446   /** Gets the last child.
447    *
448    * @return The last child, or 0 if the node has no children.
449    */
450   NodeTree<T>* last_child()
451   {
452     return wrap(g_node_last_child(gobj()));
453   }
454
455   /** Gets the last child.
456    *
457    * @return The last child, or 0 if the node has no children.
458    */
459   const NodeTree<T>* last_child() const
460   {
461     return const_cast<NodeTree<T>*>(this)->last_child();
462   }
463   _IGNORE(g_node_last_child)
464
465   /** Gets the nth child.
466    *
467    * @return The nth child, or 0 if n is too large.
468    */
469   NodeTree<T>* nth_child(int n) 
470   {
471     return wrap(g_node_nth_child(gobj(), n));
472   }
473
474   /** Gets the nth child.
475    *
476    * @return The nth child, or 0 if n is too large.
477    */
478   const NodeTree<T>* nth_child(int n) const
479   {
480     return const_cast<NodeTree<T>*>(this)->nth_child(n);
481   }
482   _IGNORE(g_node_nth_child)
483   
484   /** Gets the first sibling
485    * @return The first sibling, or 0 if the node has no siblings.
486    */
487   NodeTree<T>* first_sibling()
488   {
489     return wrap(g_node_first_sibling(gobj()));
490   }
491
492   /** Gets the first sibling
493    * @return The first sibling, or 0 if the node has no siblings.
494    */
495   const NodeTree<T>* first_sibling() const
496   {
497     return const_cast<NodeTree<T>*>(this)->first_sibling();
498   }
499   _IGNORE(g_node_first_sibling)
500
501   /** Gets the previous sibling.
502    *
503    * @return The previous sibling, or 0 if the node has no siblings.
504    */
505   NodeTree<T>* prev_sibling()
506   {
507     return wrap(g_node_prev_sibling(gobj()));
508   }
509
510   /** Gets the previous sibling.
511    *
512    * @return The previous sibling, or 0 if the node has no siblings.
513    */
514   const NodeTree<T>* prev_sibling() const
515   {
516     return const_cast<NodeTree<T>*>(this)->prev_sibling();
517   }
518   _IGNORE(g_node_prev_sibling)
519
520   /** Gets the next sibling
521    *
522    * @return The next sibling, or 0 if the node has no siblings.
523    */
524   NodeTree<T>* next_sibling()
525   {
526     return wrap(g_node_next_sibling(gobj()));
527   }
528
529   /** Gets the next sibling
530    *
531    * @return The next sibling, or 0 if the node has no siblings.
532    */
533   const NodeTree<T>* next_sibling() const
534   {
535     return const_cast<NodeTree<T>*>(this)->next_sibling();
536   }
537   _IGNORE(g_node_next_sibling)
538
539   /** Gets the last sibling.
540    *
541    * @return The last sibling, or 0 if the node has no siblings.
542    */
543   NodeTree<T>* last_sibling()
544   {
545     return wrap(g_node_last_sibling(gobj()));
546   }
547
548   /** Gets the last sibling.
549    *
550    * @return The last sibling, or 0 if the node has no siblings.
551    */
552   const NodeTree<T>* last_sibling() const
553   {
554     return const_cast<NodeTree<T>*>(this)->last_sibling();
555   }
556   _IGNORE(g_node_last_sibling)
557
558   /** Returns true if this is a leaf node.
559    *
560    * @return true if this is a leaf node.
561    */
562   bool is_leaf() const
563   {
564     return G_NODE_IS_LEAF(const_cast<GNode*>(gobj()));
565   }
566
567   /** Returns true if this is the root node.
568    *
569    * @return true if this is the root node.
570    */
571   bool is_root() const
572   {
573     return G_NODE_IS_ROOT(const_cast<GNode*>(gobj()));
574   }
575
576   /** Gets the depth of this node.
577    * The root node has a depth of 1.
578    * For the children of the root node the depth is 2. And so on.
579    *
580    * @return the depth of this node
581    */
582   guint depth() const
583   {
584     return g_node_depth(const_cast<GNode*>(gobj()));
585   }
586   _IGNORE(g_node_depth)
587
588   /** Gets the number of nodes in a tree.
589    *
590    * @param flags Which types of children are to be counted: one of TRAVERSE_ALL, TRAVERSE_LEAVES and TRAVERSE_NON_LEAVES
591    * @return The number of nodes in the tree.
592    */
593   guint node_count(TraverseFlags flags = TRAVERSE_ALL) const
594   {
595     return g_node_n_nodes(const_cast<GNode*>(gobj()), (GTraverseFlags)flags);
596   }
597   _IGNORE(g_node_n_nodes)
598
599   /** Gets the number children.
600    *
601    * @return The number of children.
602    */
603   guint child_count() const
604   {
605     return g_node_n_children(const_cast<GNode*>(gobj()));
606   }
607   _IGNORE(g_node_n_children)
608
609   /** Returns true if this is an ancestor of @a descendant.
610    * This is true if this is the parent of @a descendant,
611    * or if this is the grandparent of @a descendant etc.
612    *
613    * @param descendant A node.
614    * @return true if this is an ancestor of descendant.
615    */
616   bool is_ancestor(const NodeTree<T>& descendant) const
617   {
618     return g_node_is_ancestor(const_cast<GNode*>(gobj()), const_cast<GNode*>(descendant.gobj()));
619   }
620   _IGNORE(g_node_is_ancestor)
621
622   /** Gets the maximum height of all branches beneath this node.
623    * This is the maximum distance from the node to all leaf nodes.
624    * If root has no children, 1 is returned. If root has children, 2 is returned. And so on.
625    *
626    * @return The maximum height of all branches.
627    */
628   guint get_max_height() const
629   {
630     return g_node_max_height(const_cast<GNode*>(gobj()));
631   }
632   _IGNORE(g_node_max_height)
633
634   /** Unlinks a node from a tree, resulting in two separate trees.
635    */
636   void unlink()
637   {
638     g_node_unlink(gobj());
639   }
640   _IGNORE(g_node_unlink)
641
642 #if 0 //Commented-out because people can just use the copy constructor.
643   /** Recursively copies a node and it's data.
644    *
645    * Returns: a new node containing the copies of the data.
646    */
647   NodeTree<T>* copy_deep() const
648   {
649     //Use copy constructor instead of g_node_copy_deep to create C++ wrappers also not only the wrapped C objects.
650     return new NodeTree<T>(*this);
651   }
652 #endif
653   _IGNORE(g_node_copy_deep)
654
655   /// Accessor for this node's data
656   T& data()
657   {
658     return data_;
659   }
660
661   /// Accessor for this node's data
662   const T& data() const
663   {
664     return data_;
665   }
666
667   /** Accessor for this node's parent.
668    *
669    * @return The node's parent.
670    */
671   const NodeTree<T>* parent() const
672   {
673     return wrap(gobj()->parent);
674   }
675
676   // Do not wrap this shallow copy function, because it is not useful:
677   _IGNORE(g_node_copy)
678
679
680 private:
681
682   void clear()
683   {
684     //Free the children (not just with g_node_destroy(), to avoid the leaking of C++ wrapper objects):
685     while(NodeTree<T>* i = first_child())
686       delete i;
687
688     //Free the wrapped object (g_node_free not available)
689     g_slice_free(GNode, gobject_);
690     gobject_ = 0;
691   }
692
693   ///Create a new GNode, taking the contents of an existing node if one is specified.
694   void clone(const NodeTree<T>* node = 0)
695   {
696     //Store the this pointer in the GNode so we can discover this wrapper later:
697     gobject_ = g_node_new(reinterpret_cast<gpointer>(this));
698
699     if(node)
700     {
701       //Prepend the copied children of @node to the constructing node.
702       for(const NodeTree<T>* i = node->last_child();  i != 0; i = i->prev_sibling())
703         prepend(*(new NodeTree<T>(*i)));
704     }
705   }
706
707   /// Wrapper for invoking a TraverseFunc.
708   static gboolean c_callback_traverse(GNode* node, gpointer slot)
709   {
710     const TraverseFunc* tf = reinterpret_cast<const TraverseFunc*>(slot);
711     return (*tf)(*wrap(node));
712   }
713
714   /// Wrapper for invoking a ForeachFunc.
715   static void c_callback_foreach(GNode* node, gpointer slot)
716   {
717     const ForeachFunc* ff = reinterpret_cast<const ForeachFunc*>(slot);
718     (*ff)(*wrap(node));
719   }
720
721   /// Method for comparing a single child (Internal use).
722   static void on_compare_child(GNode* node, const T& needle, GNode** result)
723   {
724     if((0 != result) && (wrap(node)->data() == needle))
725     {
726       *result = node;
727     }
728   }
729
730   /// Wrapper for invoking a sigc::slot<void,GNode*> (Internal use).
731   static void c_callback_foreach_compare_child(GNode* node, gpointer data)
732   {
733     const ForeachFunc* slot = reinterpret_cast<const ForeachFunc*>(data);
734     (*slot)(*wrap(node));
735   }
736
737   /// Method for comparing a single node (Internal use).
738   static gboolean on_compare_node(GNode* node, const T& needle, GNode** result)
739   {
740     if(wrap(node)->data() == needle)
741     {
742       *result = node;
743       return TRUE;
744     }
745     return FALSE;
746   }
747
748   /// Wrapper for invoking a sigc::slot<gboolean,GNode*> (Internal use).
749   static gboolean c_callback_traverse_compare_node(GNode* node, gpointer data)
750   {
751     const TraverseFunc* slot = reinterpret_cast<const TraverseFunc*>(data);
752     return (*slot)(*wrap(node));
753   }
754
755
756   GNode* gobject_;
757   T data_;
758 };
759
760 } // namespace Glib