# See the License for the specific language governing permissions and
# limitations under the License.
-# management and display of ordered trees
+# Manipulation and presentation of ordered trees.
module ordered_tree
# Generic structure to manage and display an ordered tree
#
# Ordered tree are tree where the elements of a same parent are in a specific order
#
-# The class can be used as it to work with generic tree.
-# The class can also be specialized to provide more specific behavior.
+# Elements of the trees are added with the `add` method that takes a parent and
+# a sub-element.
+# If the parent is `null`, then the element is considered a root.
+#
+# ~~~~
+# var t = new OrderedTree[String]
+# t.add(null, "root")
+# t.add("root", "child1")
+# t.add("root", "child2")
+# t.add("child1", "grand-child")
+# assert t.length == 4
+# ~~~~
+#
+# By default, the elements with a same parent
+# are visited in the order they are added.
+#
+# ~~~
+# assert t.to_a == ["root", "child1", "grand-child", "child2"]
+# assert t.write_to_string == """
+# root
+# |--child1
+# | `--grand-child
+# `--child2
+# """
+# ~~~
+#
+# The `sort_with` method can be used reorder elements
+#
+# ~~~
+# t.add("root", "aaa")
+# assert t.to_a == ["root", "child1", "grand-child", "child2", "aaa"]
+# t.sort_with(alpha_comparator)
+# assert t.to_a == ["root", "aaa", "child1", "grand-child", "child2"]
+# ~~~
+#
+# This class can be used as it to work with generic trees but can also be specialized to provide more specific
+# behavior or display. It is why the internal attributes are mutable.
class OrderedTree[E: Object]
- super Streamable
+ super Writable
super Collection[E]
- # Sequence
+ # The roots of the tree (in sequence)
var roots = new Array[E]
+
+ # The branches of the trees.
+ # For each element, the ordered array of its direct sub-elements.
var sub = new HashMap[E, Array[E]]
- # Add a new element `e` in the tree
+ # Add a new element `e` in the tree.
# `p` is the parent of `e`.
# if `p` is null, then `e` is a root element.
- #
- # By defauld, the elements with a same parent
- # are displayed in the order they are added.
- #
- # The `sort_with` method can be used reorder elements
fun add(p: nullable E, e: E)
do
if p == null then
# print the full tree on `o`
# Write a ASCII-style tree and use the `display` method to label elements
- redef fun write_to(stream: OStream)
+ redef fun write_to(stream: Writer)
do
- var last = roots.last
for r in roots do
stream.write display(r)
stream.write "\n"
end
end
- private fun sub_write_to(o: OStream, e: E, prefix: String)
+ private fun sub_write_to(o: Writer, e: E, prefix: String)
do
if not sub.has_key(e) then return
var subs = sub[e]
# Sort roots and other elements using a comparator method
# This method basically sorts roots then each group of children
- fun sort_with(comparator: Comparator[E])
+ fun sort_with(comparator: Comparator)
do
comparator.sort(roots)
for a in sub.values do
var iterators = new Array[Iterator[E]]
- init(tree: OrderedTree[E]) do
- self.tree = tree
-
+ init do
if not tree.is_empty then
iterators.add tree.roots.iterator
end