From f58280599b4d78eaf1aea362e9cfa65ad2630a57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Plach=C3=BD?= <plachste@fit.cvut.cz>
Date: Sun, 19 Apr 2015 19:49:29 +0200
Subject: [PATCH] Unranked tree change

---
 .../src/tree/generate/RandomTreeFactory.cpp   |  2 +-
 alib2data/src/tree/TreeFromXMLParser.cpp      |  2 +-
 alib2data/src/tree/TreeToXMLComposer.cpp      |  2 +-
 .../src/tree/UnrankedTree/UnrankedNode.cpp    | 63 ++++++++++++++-----
 .../src/tree/UnrankedTree/UnrankedNode.h      | 24 ++++---
 .../src/tree/UnrankedTree/UnrankedTree.cpp    | 22 +++++--
 .../src/tree/UnrankedTree/UnrankedTree.h      |  6 +-
 alib2data/test-src/tree/TreeTest.cpp          | 50 ++++++++-------
 makefile                                      |  1 -
 9 files changed, 116 insertions(+), 56 deletions(-)

diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
index ef9398254c..2ec371074f 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.cpp
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
@@ -209,7 +209,7 @@ UnrankedTree RandomTreeFactory::generateUnrankedTree(int depth, int nodesCount,
 	for (std::vector<char>::iterator it = alphabet.begin(); it != alphabet.end(); ++it) {
 		treeAlphabet.insert(alphabet::LabeledSymbol(*it));
 	}
-	UnrankedTree tree (treeAlphabet, root -> createUnrankedNode());
+	UnrankedTree tree (treeAlphabet, *std::move(root -> createUnrankedNode()));
 	delete root;
 	return tree;
 }
diff --git a/alib2data/src/tree/TreeFromXMLParser.cpp b/alib2data/src/tree/TreeFromXMLParser.cpp
index d371583070..d5df89db69 100644
--- a/alib2data/src/tree/TreeFromXMLParser.cpp
+++ b/alib2data/src/tree/TreeFromXMLParser.cpp
@@ -43,7 +43,7 @@ namespace tree {
 
 		std::set<alphabet::LabeledSymbol> alphabet = parseAlphabet(input);
 		UnrankedNode * root = parseUnrankedNode(input);
-		UnrankedTree tree(alphabet, root);
+		UnrankedTree tree(alphabet, std::move(*root));
 		popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::TREE_UNRANKED_TREE);
 		return tree;
 	}
diff --git a/alib2data/src/tree/TreeToXMLComposer.cpp b/alib2data/src/tree/TreeToXMLComposer.cpp
index 25833ae3c7..82e28b7cfe 100644
--- a/alib2data/src/tree/TreeToXMLComposer.cpp
+++ b/alib2data/src/tree/TreeToXMLComposer.cpp
@@ -55,7 +55,7 @@ std::list<sax::Token> TreeToXMLComposer::compose(const UnrankedTree& tree) const
 	out.push_back(sax::Token(alib::Names::TREE_UNRANKED_TREE, sax::Token::TokenType::START_ELEMENT));
 
 	composeAlphabet(out, tree.getAlphabet());
-	composeNode(out, *tree.getRoot());
+	composeNode(out, tree.getRoot());
 
 	out.push_back(sax::Token(alib::Names::TREE_UNRANKED_TREE, sax::Token::TokenType::END_ELEMENT));
 	return out;
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp b/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp
index dd12fd453f..8ac61818a7 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp
+++ b/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp
@@ -12,21 +12,38 @@
 
 namespace tree {
 
-UnrankedNode::UnrankedNode(const alphabet::LabeledSymbol& symbol, std::list<UnrankedNode *> & children) : symbol(symbol), parent(NULL), children(children) {
-	for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it) {
+UnrankedNode::UnrankedNode(const alphabet::LabeledSymbol& symbol, const std::list<UnrankedNode *> & children) : symbol(symbol), children(children) {
+	for (std::list<UnrankedNode *>::const_iterator it = children.begin(); it != children.end(); ++it) {
 		(*it) -> parent = this;
 	}
 }
 
-UnrankedNode::UnrankedNode(const UnrankedNode & other) : symbol(other.symbol.getLabel()) {
+UnrankedNode::UnrankedNode(const UnrankedNode & other) : symbol(other.symbol) {
 	children = std::list<UnrankedNode *>();
 	for (std::list<UnrankedNode *>::const_iterator it = other.children.begin(); it != other.children.end(); ++it) {
-		UnrankedNode * child = new UnrankedNode(**it);
+		UnrankedNode * child = (*it) -> clone();
 		child -> parent = this;
 		children.push_back(child);
 	}
 }
 
+UnrankedNode::UnrankedNode(UnrankedNode && other) : symbol(std::move(other.symbol)) {
+	children = std::list<UnrankedNode *>();
+	for (std::list<UnrankedNode *>::const_iterator it = other.children.begin(); it != other.children.end(); ++it) {
+		UnrankedNode * child = std::move(**it).plunder();
+		child -> parent = this;
+		children.push_back(child);
+	}
+}
+
+UnrankedNode * UnrankedNode::clone() const {
+	return new UnrankedNode(*this);
+}
+
+UnrankedNode * UnrankedNode::plunder() && {
+	return new UnrankedNode(std::move(*this));
+}
+
 UnrankedNode::~UnrankedNode() {
 	for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it)
 	{
@@ -34,18 +51,32 @@ UnrankedNode::~UnrankedNode() {
 	}
 }
 
+UnrankedNode & UnrankedNode::operator=(const UnrankedNode & other) {
+	if (this == &other) return *this;
+	*this = UnrankedNode(other);
+	return *this;
+}
+
+UnrankedNode & UnrankedNode::operator=(UnrankedNode && other) {
+	std::swap(symbol, other.symbol);
+	std::swap(children, other.children);
+	for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it)
+		(*it) -> attachUnrankedTree(tree);
+	return *this;
+}
+
 void UnrankedNode::setSymbol(alphabet::LabeledSymbol & symbol) {
 	this -> symbol = symbol;
 	checkValidSymbol();
 }
 
-void UnrankedNode::setUnrankedTree(UnrankedTree * tree) {
+void UnrankedNode::attachUnrankedTree(UnrankedTree * tree) {
 	if (this -> tree == tree) return;
 	this -> tree = tree;
 	checkValidSymbol();
 	for (std::list<UnrankedNode *>::iterator i = children.begin(); i != children.end(); ++i)
 	{
-		(*i) -> setUnrankedTree(tree);
+		(*i) -> attachUnrankedTree(tree);
 	}
 }
 
@@ -64,20 +95,20 @@ bool UnrankedNode::containsSymbol(const alphabet::LabeledSymbol & symbol) const
 	return false;
 }
 
-UnrankedNode * UnrankedNode::extract() {
+UnrankedNode & UnrankedNode::extract() {
 	parent -> children.remove(this);
 	parent = NULL;
-	setUnrankedTree(NULL);
-	return this;
+	attachUnrankedTree(NULL);
+	return *this;
 }
 
-void UnrankedNode::pushBackChild(UnrankedNode * child) {
-	child -> setUnrankedTree(tree);
-	children.push_back(child);
+void UnrankedNode::pushBackChild(UnrankedNode & child) {
+	child.attachUnrankedTree(tree);
+	children.push_back(&child);
 }
 
-void UnrankedNode::insertSibling(UnrankedNode * sibling) {
-	parent -> insertChild(this, sibling);
+void UnrankedNode::insertSibling(UnrankedNode & sibling) {
+	parent -> insertChild(this, &sibling);
 }
 
 void UnrankedNode::insertChild(UnrankedNode * position, UnrankedNode * child) {
@@ -111,8 +142,8 @@ void UnrankedNode::switchSubtree(UnrankedNode * other) {
 	other -> parent = thisParent;
 	UnrankedTree * thisTree = tree;
 	UnrankedTree * otherTree = other -> tree;
-	setUnrankedTree(otherTree);
-	other -> setUnrankedTree(thisTree);
+	attachUnrankedTree(otherTree);
+	other -> attachUnrankedTree(thisTree);
 }
 
 bool UnrankedNode::operator < (const UnrankedNode & other) const {
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedNode.h b/alib2data/src/tree/UnrankedTree/UnrankedNode.h
index 201f9b31fe..e8f7951247 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedNode.h
+++ b/alib2data/src/tree/UnrankedTree/UnrankedNode.h
@@ -26,29 +26,37 @@ namespace tree {
 class UnrankedNode {
 private:
 	alphabet::LabeledSymbol symbol;
-	UnrankedNode * parent;
+	UnrankedNode * parent = NULL;
 	std::list<UnrankedNode *> children;
 	UnrankedTree * tree = NULL;
 
-	void setUnrankedTree(UnrankedTree *);
+	void attachUnrankedTree(UnrankedTree *);
 	void changeChild(UnrankedNode * child, UnrankedNode * other);
 	void insertChild(UnrankedNode * position, UnrankedNode * child);
 public:
-	explicit UnrankedNode(const alphabet::LabeledSymbol& symbol, std::list<UnrankedNode *> & children);
-	UnrankedNode(const UnrankedNode & other);
+	explicit UnrankedNode(const alphabet::LabeledSymbol& symbol, const std::list<UnrankedNode *> & children);
+	explicit UnrankedNode(const UnrankedNode &);
+	explicit UnrankedNode(UnrankedNode &&);
 	~UnrankedNode();
+	UnrankedNode & operator= (const UnrankedNode &);
+	UnrankedNode & operator= (UnrankedNode &&);
+
+	UnrankedNode * clone() const;
+	UnrankedNode * plunder() &&;
+
 
 	const alphabet::LabeledSymbol& getSymbol() const {return symbol;}
 	void setSymbol(alphabet::LabeledSymbol&);
 	UnrankedNode * getParent() const {return parent;}
-	const std::list<UnrankedNode *> & getChildren() const {return children;}
+	const std::list<const UnrankedNode *> & getChildren() const {return *reinterpret_cast<const std::list<const UnrankedNode *> *>(&children);}
+	const std::list<UnrankedNode *> & getChildren() {return children;}
 	UnrankedTree * getUnrankedTree() const {return tree;}
 	bool containsSymbol(const alphabet::LabeledSymbol &) const;
 	void checkValidSymbol() const;
 
-	UnrankedNode * extract();
-	void pushBackChild(UnrankedNode *);
-	void insertSibling(UnrankedNode *);
+	UnrankedNode & extract();
+	void pushBackChild(UnrankedNode &);
+	void insertSibling(UnrankedNode &);
 	void switchSubtree(UnrankedNode * other);
 
 	bool operator < (const UnrankedNode& other) const;
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp b/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp
index 7faa8b02af..6bb837b328 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp
+++ b/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp
@@ -12,15 +12,27 @@
 
 namespace tree {
 
-UnrankedTree::UnrankedTree(std::set<alphabet::LabeledSymbol> alphabet, UnrankedNode * root) : alphabet(alphabet), root(root) {
-	if (root -> tree != NULL) throw TreeException("Root is already in a tree");
-	root -> setUnrankedTree(this);
+UnrankedTree::UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode & root) : alphabet(alphabet) {
+	this -> root = new UnrankedNode(root);
+	this -> root -> attachUnrankedTree(this);
+}
+
+UnrankedTree::UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode && root) : alphabet(alphabet) {
+	this -> root = new UnrankedNode(root);
+	if (this -> root -> tree != NULL) throw TreeException("Root is already in a tree");
+	this -> root -> attachUnrankedTree(this);
 }
 
 UnrankedTree::UnrankedTree(const UnrankedTree & other) {
 	alphabet = other.alphabet;
-	root = new UnrankedNode(*(other.root));
-	root -> setUnrankedTree(this);
+	root = other.root -> clone();
+	root -> attachUnrankedTree(this);
+}
+
+UnrankedTree::UnrankedTree(UnrankedTree && other) {
+	alphabet = std::move(other.alphabet);
+	root = std::move(*other.root).clone();
+	root -> attachUnrankedTree(this);
 }
 
 UnrankedTree::~UnrankedTree() {
diff --git a/alib2data/src/tree/UnrankedTree/UnrankedTree.h b/alib2data/src/tree/UnrankedTree/UnrankedTree.h
index 35164f6b83..64f2c838f0 100644
--- a/alib2data/src/tree/UnrankedTree/UnrankedTree.h
+++ b/alib2data/src/tree/UnrankedTree/UnrankedTree.h
@@ -27,8 +27,10 @@ protected:
 	std::set<alphabet::LabeledSymbol> alphabet;
 	UnrankedNode * root;
 public:
-	explicit UnrankedTree(std::set<alphabet::LabeledSymbol> alphabet, UnrankedNode * root);
+	explicit UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode & root);
+	explicit UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode && root);
 	UnrankedTree(const UnrankedTree &);
+	explicit UnrankedTree(UnrankedTree &&);
 
 	~UnrankedTree();
 
@@ -39,7 +41,7 @@ public:
 	/**
 	 * @return tree root
 	 */
-	UnrankedNode * getRoot() const {return root;}
+	UnrankedNode & getRoot() const {return *root;}
 
 	const std::set<alphabet::LabeledSymbol> & getAlphabet() const {return alphabet;}
 
diff --git a/alib2data/test-src/tree/TreeTest.cpp b/alib2data/test-src/tree/TreeTest.cpp
index 63c68aa4e5..c8043e3c42 100644
--- a/alib2data/test-src/tree/TreeTest.cpp
+++ b/alib2data/test-src/tree/TreeTest.cpp
@@ -80,14 +80,15 @@ void TreeTest::testRankedTreeParser() {
 		std::cout << std::endl;
 		tree2.getRoot().nicePrint(std::cout);
 	}
-
+/*
 	std::string s = "a2a2a2b1a2c0c0c0c0c0";
 	int itmp = 0;
 	tree::RankedNode * node = prefixToNode(s, itmp);
 	std::set<alphabet::RankedSymbol> al;
-	for (int i = 0; i < s.length(); i += 2) al.insert(alphabet::RankedSymbol(s[i], (int) (s[i+1] - '0')));
+	for (unsigned i = 0; i < s.length(); i += 2) al.insert(alphabet::RankedSymbol(s[i], (int) (s[i+1] - '0')));
 	tree::RankedTree t(al, std::move(*node));
 	alib::DataFactory::toStdout(t);
+*/
 }
 
 void TreeTest::testRankedTreeCompare() {
@@ -264,10 +265,10 @@ void TreeTest::testUnrankedTreeParser() {
 	std::list<tree::UnrankedNode *> children1 {node2, node4};
 	tree::UnrankedNode * node1 = new tree::UnrankedNode(a, children1);
 
-	tree::UnrankedTree tree(alphabet, node1);
+	tree::UnrankedTree tree(alphabet, std::move(*node1));
 
 	CPPUNIT_ASSERT( tree == tree );
-	tree.getRoot() -> nicePrint(std::cout);
+	tree.getRoot().nicePrint(std::cout);
 	{
 		std::list<sax::Token> tokens = alib::DataFactory::toTokens(tree);
 		std::string tmp;
@@ -280,7 +281,7 @@ void TreeTest::testUnrankedTreeParser() {
 
 		CPPUNIT_ASSERT( tree == tree2 );
 		std::cout << std::endl;
-		tree2.getRoot() -> nicePrint(std::cout);
+		tree2.getRoot().nicePrint(std::cout);
 	}
 }
 
@@ -328,8 +329,8 @@ void TreeTest::testUnrankedTreeCompare() {
 	std::list<tree::UnrankedNode *> children5 {node6, node7};
 	tree::UnrankedNode * node5 = new tree::UnrankedNode(a, children5);
 
-	tree::UnrankedTree tree1(alphabet, node1);
-	tree::UnrankedTree tree2(alphabet, node5);
+	tree::UnrankedTree tree1(alphabet, std::move(*node1));
+	tree::UnrankedTree tree2(alphabet, std::move(*node5));
 
 	CPPUNIT_ASSERT( tree1 != tree2 );
 	CPPUNIT_ASSERT( tree1 < tree2 );
@@ -355,7 +356,7 @@ void TreeTest::testUnrankedTreeSymbolValidityCheck() {
 	std::list<tree::UnrankedNode *> children1 {node2, node4};
 	tree::UnrankedNode * node1 = new tree::UnrankedNode(a, children1);
 
-	CPPUNIT_ASSERT_THROW(tree::UnrankedTree tree1(alphabet, node1), exception::AlibException);
+	CPPUNIT_ASSERT_THROW(tree::UnrankedTree tree1(alphabet, *node1), exception::AlibException);
 
 	std::list<tree::UnrankedNode *> children6 (0);
 	tree::UnrankedNode * node6 = new tree::UnrankedNode(e, children6);
@@ -367,10 +368,10 @@ void TreeTest::testUnrankedTreeSymbolValidityCheck() {
 	tree::UnrankedNode * node5 = new tree::UnrankedNode(a, children5);
 
 	tree::UnrankedTree * tree;
-	CPPUNIT_ASSERT_NO_THROW(tree = new tree::UnrankedTree(alphabet, node5));
-	CPPUNIT_ASSERT_NO_THROW(node6 -> setSymbol(c));
-	CPPUNIT_ASSERT_THROW(node6 -> setSymbol(d), exception::AlibException);
-	CPPUNIT_ASSERT_NO_THROW(node7 -> setSymbol(a));
+	CPPUNIT_ASSERT_NO_THROW(tree = new tree::UnrankedTree(alphabet, std::move(*node5)));
+	CPPUNIT_ASSERT_NO_THROW((*tree -> getRoot().getChildren().begin()) -> setSymbol(c));
+	CPPUNIT_ASSERT_THROW((*tree -> getRoot().getChildren().begin()) -> setSymbol(d), exception::AlibException);
+	CPPUNIT_ASSERT_NO_THROW((*(++tree -> getRoot().getChildren().begin())) -> setSymbol(a));
 	CPPUNIT_ASSERT_THROW(tree -> removeSymbol(a), exception::AlibException);
 	CPPUNIT_ASSERT(tree -> removeSymbol(e));
 	delete tree;
@@ -403,23 +404,30 @@ void TreeTest::testUnrankedTreeSubtreeSwitch() {
 	std::list<tree::UnrankedNode *> children5 {node6, node7};
 	tree::UnrankedNode * node5 = new tree::UnrankedNode(a, children5);
 
-	tree::UnrankedTree tree1(alphabet1, node1);
+	tree::UnrankedTree tree1(alphabet1, std::move(*node1));
 	tree::UnrankedTree tree1Copy (tree1);
-	tree::UnrankedTree tree2(alphabet2, node5);
+	tree::UnrankedTree tree2(alphabet2, std::move(*node5));
 	tree::UnrankedTree tree2Copy (tree2);
 
-	node3 -> switchSubtree(node7);
-	node3 -> switchSubtree(node7);
+	(*(*tree1.getRoot().getChildren().begin()) -> getChildren().begin()) -> switchSubtree(*(++tree2.getRoot().getChildren().begin()));
+	(*(*tree1.getRoot().getChildren().begin()) -> getChildren().begin()) -> switchSubtree(*(++tree2.getRoot().getChildren().begin()));
 
 	CPPUNIT_ASSERT(tree1 == tree1Copy);
 	CPPUNIT_ASSERT(tree2 == tree2Copy);
-	CPPUNIT_ASSERT_THROW(node4 -> switchSubtree(node6), exception::AlibException);
+	CPPUNIT_ASSERT_THROW((*(++tree1.getRoot().getChildren().begin())) -> switchSubtree(*tree2.getRoot().getChildren().begin()), exception::AlibException);
 
-	node6 -> setSymbol(c);
-	node1 -> switchSubtree(node5);
+	tree::UnrankedTree tree3(tree1Copy);
+	tree::UnrankedTree tree4(tree2Copy);
 
-	CPPUNIT_ASSERT(*(tree1.getRoot()) < *(tree2Copy.getRoot()));
-	CPPUNIT_ASSERT(*(tree2.getRoot()) == *(tree1Copy.getRoot()));
+	(*tree4.getRoot().getChildren().begin()) -> setSymbol(c);
 
+	tree3.getRoot().nicePrint();
+	std::cout << std::endl;
+	tree4.getRoot().nicePrint();
+
+	tree3.getRoot().switchSubtree(&tree4.getRoot());
+
+	CPPUNIT_ASSERT(tree3.getRoot() < tree2Copy.getRoot());
+	CPPUNIT_ASSERT(tree4.getRoot() == tree1Copy.getRoot());
 }
 
diff --git a/makefile b/makefile
index b6e0f53fb8..7013d465d5 100644
--- a/makefile
+++ b/makefile
@@ -23,7 +23,6 @@ SUBDIRS_BINS = acat2 \
 		astat2 \
 		astringology2 \
 		atrim2 \
-		trand \
 		tniceprint \
 
 
-- 
GitLab