diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp index ef9398254c146ee0b29ec09a50057ca0c69d7272..2ec371074f6980626359820d4a698cb383131cc5 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 d37158307027ad4e0dd370a41c67d6bb09e5ab18..d5df89db69aa56ec0fb9e1b36acf77f0142daaf7 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 25833ae3c785852d6625ff4ae6306f39d7453867..82e28b7cfefac806846fe9a5eef5446dae2a2112 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 dd12fd453f083e722b0c80013a3525db22b9cb91..8ac61818a7202e428a23361256486ef04cb3c5b8 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 201f9b31fe98df923292b7d15ad5676f8ae155ac..e8f7951247ac3d59288cf81810dbb2baba681dcd 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 7faa8b02af14d301397cd9ddabd6db9f3eb1c628..6bb837b328ab53176991ab343d48097a25ac3610 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 35164f6b83d5a018d2e71f10edd647eea1716ff3..64f2c838f0fc9f643ed27f533004a130ee077115 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 63c68aa4e5120d66233a3de510f6492d8465033c..c8043e3c42deba316a714129d542dca9e34cd53d 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 b6e0f53fb870b2ad8d36be7676c739a98f8564fc..7013d465d51248d84d4c79f118de8106790d9db0 100644 --- a/makefile +++ b/makefile @@ -23,7 +23,6 @@ SUBDIRS_BINS = acat2 \ astat2 \ astringology2 \ atrim2 \ - trand \ tniceprint \