import mem import vec import io:* import str:* obj tree (Object) { var data: T var parent: *tree var children: vec::vec<*tree> fun construct(dataIn: ref T): *tree { mem::maybe_copy_construct(&data, &dataIn) parent = mem::null>() children.construct() return this } fun construct(dataIn: ref T, c: ref vec::vec<*tree>): *tree { mem::maybe_copy_construct(&data, &dataIn) parent = mem::null>() children.copy_construct(&c) children.for_each(fun(i: *tree) { i->parent = this }) return this } // Some of these don't really make much sense considering this tree is all about // heap allocated pointers. Best to have it for saftey, though fun copy_construct(old: *tree) { mem::maybe_copy_construct(&data, &old->data) parent = old->parent children.copy_construct(&old->children) } // ditto fun operator=(other: tree):void { destruct() copy_construct(&other) } fun operator==(other: ref tree):bool { return data == other.data } fun destruct() { mem::maybe_destruct(&data) children.destruct() } fun add_child(c: *tree) { children.add(c) c->parent = this } fun add_children(c: vec::vec<*tree>) { for (var i = 0; i < c.size; i++;) { children.add(c[i]) c[i]->parent = this } } fun set_child(i: int, c: *tree) { children[i] = c c->parent = this } fun replace_child(old_c: *tree, new_c: *tree) { children[children.find(old_c)] = new_c new_c->parent = this } fun remove_child(old_c: *tree) { children.remove(children.find(old_c)) } fun clone(): *tree { return mem::new>()->construct(data, children.map(fun(c: *tree): *tree return c->clone();)) } fun clone(f: fun(ref T): T): *tree { return mem::new>()->construct(f(data), children.map(fun(c: *tree): *tree return c->clone(f);)) } }