/** * @param tree * @return */ @Pure @ExtensionMethod @ReturnNonnull @Recursive public static <T> AbstractUnmodifiableIterable<T> NodeValuesPostOrder(final IMultiTree<T> tree) { com.google.common.base.Preconditions.checkNotNull(tree); if (tree.IsTreeNode()) { final IMultiTreeNode<T> treeNode = tree.AsTreeNode(); assert treeNode != null; return Iterables.Concat( Iterables.Concat( Iterables.Map( treeNode.GetSubtrees(), new Func1<IMultiTree<T>, Iterable<T>>() { @Override public Iterable<T> DoFunc(final IMultiTree<T> input) { assert input != null; return MultiTrees.NodeValuesPreOrder(input); } })), treeNode.GetNodeValue()); } else { assert tree.IsEmptyTree(); return Iterables.EmptyUnmodifiableIterable(); } }
/** * @param tree * @param foldTreeFunc * @param emptyTreeValue * @return */ @Pure @ExtensionMethod @Recursive public static <TNode, TOut> TOut Fold( final IMultiTree<? extends TNode> tree, final Func2<? super TNode, ? super Iterable<TOut>, ? extends TOut> foldTreeFunc, @Nullable final TOut emptyTreeValue) { com.google.common.base.Preconditions.checkNotNull(foldTreeFunc); com.google.common.base.Preconditions.checkNotNull(tree); if (!tree.IsEmptyTree()) { final IMultiTreeNode<TNode> multiTreeNode = MultiTrees.AsMultiTreeNodeWhenReadOnly(tree); assert multiTreeNode != null; return foldTreeFunc.DoFunc( multiTreeNode.GetNodeValue(), Iterables.Map( multiTreeNode.GetSubtrees(), new Func1<IMultiTree<TNode>, TOut>() { @Override public TOut DoFunc(IMultiTree<TNode> subTree) { return MultiTrees.Fold(subTree, foldTreeFunc, emptyTreeValue); } })); } else { return emptyTreeValue; } }