/CS/migrated/tags/PRE_THING_FACTORIES/include/csutil/tree.h

# · C++ Header · 117 lines · 66 code · 13 blank · 38 comment · 21 complexity · 7730cafdd04cb70b59e765a7bc88089c MD5 · raw file

  1. /*
  2. Copyright (C) 2000 by Norman Krämer
  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. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public
  12. License along with this library; if not, write to the Free
  13. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #ifndef __CS_CSTREENODE_H__
  16. #define __CS_CSTREENODE_H__
  17. #include "csutil/csvector.h"
  18. /**
  19. * A generic tree class.
  20. */
  21. class csTreeNode
  22. {
  23. public:
  24. /// Returns true if this node has no children.
  25. bool IsLeaf ()
  26. { return children.Length () == 0; }
  27. /// Remove a child node.
  28. void RemoveChild (csTreeNode *child)
  29. { int idx = children.Find (child); if (idx != -1) children.Delete (idx); }
  30. /// Add a child node.
  31. void AddChild (csTreeNode *child)
  32. { children.Push (child); child->parent = this; }
  33. /// Create node, optionally as a child of <code>theParent</code>.
  34. csTreeNode (csTreeNode *theParent=NULL)
  35. { parent=theParent; if (parent) parent->children.Push (this); }
  36. virtual ~csTreeNode ()
  37. {
  38. int i;
  39. for(i=children.Length ()-1; i>=0; i--)
  40. delete (csTreeNode*)children.Get (i);
  41. if (parent)
  42. parent->RemoveChild (this);
  43. }
  44. /**
  45. * Execute a function on this node and its children. Do this in "DepthSearchFirst" order, that is check a childs children
  46. * before testing the next direct child.
  47. * Returns the last node where TreeFunc resulted in TRUE. If stopOnSuccess is true, then execution is stoped after first
  48. * successful execution of TreeFunc.
  49. * SelBranch lets you decide which children to select for further investugation. NULL means all children.
  50. */
  51. csTreeNode *DSF (bool (*TreeFunc)(csTreeNode *node, void* param, bool stopOnSuccess),
  52. bool (*SelBranch)(csTreeNode *node), void* param, bool stopOnSuccess)
  53. {
  54. csTreeNode *foundNode = NULL;
  55. int i=0;
  56. bool dive;
  57. if (TreeFunc (this, param, stopOnSuccess))
  58. foundNode = this;
  59. while (i<children.Length () && !(foundNode && stopOnSuccess))
  60. {
  61. dive = (SelBranch == NULL) || SelBranch ((csTreeNode*)children.Get (i));
  62. if (dive)
  63. foundNode = ((csTreeNode*)children.Get (i))->DSF (TreeFunc, SelBranch,
  64. param, stopOnSuccess);
  65. i++;
  66. }
  67. return foundNode;
  68. }
  69. /**
  70. * Execute a function on this node and its children. Do this in "BreadthSearchFirst" order, that is check first all
  71. * direct children before diving into subchildren.
  72. * Returns the last node where TreeFunc resulted in TRUE. If stopOnSuccess is true, then execution is stoped after first
  73. * successful execution of TreeFunc.
  74. * SelBranch lets you decide which children to select for further investugation. NULL means all children.
  75. */
  76. csTreeNode *BSF (bool (*TreeFunc)(csTreeNode *node, void* param, bool stopOnSuccess),
  77. bool (*SelBranch)(csTreeNode *node), void* param, bool stopOnSuccess)
  78. {
  79. csTreeNode *node, *foundNode = NULL;
  80. csVector fifo;
  81. fifo.Push (this);
  82. while (fifo.Length () > 0 && !(foundNode && stopOnSuccess))
  83. {
  84. node = (csTreeNode*)fifo.Get (0); fifo.Delete (0);
  85. if (TreeFunc (node, param, stopOnSuccess))
  86. foundNode = node;
  87. if (!node->IsLeaf () && (SelBranch==NULL || SelBranch (node)))
  88. {
  89. int i;
  90. for (i=0; i < node->children.Length (); i++ )
  91. fifo.Push (node->children.Get (i));
  92. }
  93. }
  94. fifo.DeleteAll ();
  95. return foundNode;
  96. }
  97. public:
  98. csTreeNode *parent; // parent node or NULL if toplevel
  99. csVector children; // node children
  100. };
  101. #endif // __CS_CSTREENODE_H__