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