diff --git a/alib2data/src/tree/ranked/RankedNode.cpp b/alib2data/src/tree/ranked/RankedNode.cpp index df4703674dc9642e279d0cb8fdeb58034b530ffa..b1b761514335c1461bc4969e378a02e23e4b67e1 100644 --- a/alib2data/src/tree/ranked/RankedNode.cpp +++ b/alib2data/src/tree/ranked/RankedNode.cpp @@ -15,34 +15,34 @@ namespace tree { -RankedNode::RankedNode ( alphabet::RankedSymbol symbol, std::vector < RankedNode * > children ) : symbol ( std::move ( symbol ) ), children ( std::move ( children ) ), parentTree ( NULL ) { +RankedNode::RankedNode ( alphabet::RankedSymbol symbol, std::vector < RankedNode * > children ) : symbol ( std::move ( symbol ) ), children ( std::move ( children ) ), alphabet ( NULL ) { if ( this->children.size ( ) != this->symbol.getRank ( ).getData ( ) ) throw TreeException ( "Number of children doesn't match the rank of the symbol" ); for ( auto & element : this->children ) element->parent = this; - this->attachTree ( NULL ); + this->attachAlphabet ( NULL ); this->parent = NULL; } -RankedNode::RankedNode ( const RankedNode & other ) : symbol ( other.symbol ), parentTree ( NULL ) { +RankedNode::RankedNode ( const RankedNode & other ) : symbol ( other.symbol ), alphabet ( NULL ) { for ( const auto & element : other.children ) children.push_back ( element->clone ( ) ); for ( auto & element : this->children ) element->parent = this; - this->attachTree ( NULL ); + this->attachAlphabet ( NULL ); this->parent = NULL; } -RankedNode::RankedNode ( RankedNode && other ) noexcept : symbol ( std::move ( other.symbol ) ), children ( std::move ( other.children ) ), parentTree ( NULL ) { +RankedNode::RankedNode ( RankedNode && other ) noexcept : symbol ( std::move ( other.symbol ) ), children ( std::move ( other.children ) ), alphabet ( NULL ) { other.children.clear ( ); for ( auto & element : this->children ) element->parent = this; - this->attachTree ( NULL ); + this->attachAlphabet ( NULL ); this->parent = NULL; } @@ -58,12 +58,12 @@ RankedNode & RankedNode::operator =( const RankedNode & other ) { RankedNode & RankedNode::operator =( RankedNode && other ) noexcept { std::swap ( this->symbol, other.symbol ); std::swap ( this->children, other.children ); - std::swap ( this->parentTree, other.parentTree ); // this->parentTree is stored within other.parentTree and it is reattached on the next line + std::swap ( this->alphabet, other.alphabet ); // this->alphabet is stored within other.alphabet and it is reattached on the next line for ( auto & element : this->children ) element->parent = this; - this->attachTree ( other.parentTree ); + this->attachAlphabet ( other.alphabet ); return * this; } @@ -96,20 +96,20 @@ void RankedNode::setSymbol ( alphabet::RankedSymbol symbol ) { this->symbol = std::move ( symbol ); - if ( ( this->parentTree != NULL ) && ( this->parentTree->getAlphabet ( ).find ( this->symbol ) == this->parentTree->getAlphabet ( ).end ( ) ) ) throw TreeException ( "Symbol is not in the alphabet" ); + if ( ( this->alphabet != NULL ) && ( this->alphabet->count ( this->symbol ) == 0 ) ) throw TreeException ( "Symbol is not in the alphabet" ); } void RankedNode::swap ( RankedNode & other ) { - const RankedAlphabet * thisParentTree = this->parentTree; - const RankedAlphabet * otherParentTree = other.parentTree; + const std::set < alphabet::RankedSymbol > * thisParentTree = this->alphabet; + const std::set < alphabet::RankedSymbol > * otherParentTree = other.alphabet; RankedNode tmp = std::move ( other ); other = std::move ( * this ); * this = std::move ( tmp ); - this->attachTree ( thisParentTree ); - other.attachTree ( otherParentTree ); + this->attachAlphabet ( thisParentTree ); + other.attachAlphabet ( otherParentTree ); } RankedNode * RankedNode::clone ( ) const { @@ -171,15 +171,15 @@ bool RankedNode::testSymbol ( const alphabet::RankedSymbol & symbol ) const { return false; } -bool RankedNode::attachTree ( const RankedAlphabet * tree ) { - if ( this->parentTree == tree ) return true; +bool RankedNode::attachAlphabet ( const std::set < alphabet::RankedSymbol > * alphabet ) { + if ( this->alphabet == alphabet ) return true; - this->parentTree = tree; + this->alphabet = alphabet; for ( const auto & child : this->children ) - if ( !child->attachTree ( tree ) ) return false; + if ( !child->attachAlphabet ( alphabet ) ) return false; - if ( ( this->parentTree != NULL ) && ( this->parentTree->getAlphabet ( ).find ( this->symbol ) == this->parentTree->getAlphabet ( ).end ( ) ) ) return false; + if ( ( this->alphabet != NULL ) && ( this->alphabet->count ( this->symbol ) == 0 ) ) return false; return true; } diff --git a/alib2data/src/tree/ranked/RankedNode.h b/alib2data/src/tree/ranked/RankedNode.h index 9303af9ec1cb3223dc62451151b2d88393c91ce0..f967ae40a6d8f453c4294f4d29ce1210052ab164 100644 --- a/alib2data/src/tree/ranked/RankedNode.h +++ b/alib2data/src/tree/ranked/RankedNode.h @@ -32,22 +32,12 @@ protected: /** * Parent tree contanining this instance of RankedTree */ - const RankedAlphabet * parentTree; - - /** - * @copydoc RankedNode::cloneAsUnranked() const - */ - UnrankedNode * cloneAsUnranked ( ) const; - - /** - * @copydoc RankedNode::testSymbol() const - */ - bool testSymbol ( const alphabet::RankedSymbol & symbol ) const; + const std::set < alphabet::RankedSymbol > * alphabet; /** * @copydoc RankedNode::attachTree() */ - bool attachTree ( const RankedAlphabet * tree ); + bool attachAlphabet ( const std::set < alphabet::RankedSymbol > * tree ); /** * @copydoc RankedNode::computeMinimalAlphabet() @@ -73,6 +63,16 @@ public: */ RankedNode * plunder ( ) &&; + /** + * @copydoc RankedNode::cloneAsUnranked() const + */ + UnrankedNode * cloneAsUnranked ( ) const; + + /** + * @copydoc RankedNode::testSymbol() const + */ + bool testSymbol ( const alphabet::RankedSymbol & symbol ) const; + /** * @return children */ diff --git a/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp b/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp index af87c7481ccefe0a7952bb6b6f334f523141ebac..992ebc0488dc8b569abd6994b0c36be585b5d80e 100644 --- a/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp +++ b/alib2data/src/tree/ranked/RankedNonlinearPattern.cpp @@ -44,11 +44,11 @@ RankedNonlinearPattern::RankedNonlinearPattern ( alphabet::RankedSymbol subtreeW } RankedNonlinearPattern::RankedNonlinearPattern ( const RankedNonlinearPattern & other ) : RankedNonlinearPatternAlphabet ( other ), pattern ( other.pattern->clone ( ) ) { - this->pattern->attachTree ( this ); + this->pattern->attachAlphabet ( & ( this->getAlphabet() ) ); } RankedNonlinearPattern::RankedNonlinearPattern ( RankedNonlinearPattern && other ) noexcept : RankedNonlinearPatternAlphabet ( other ), pattern ( other.pattern ) { - this->pattern->attachTree ( this ); + this->pattern->attachAlphabet ( & ( this->getAlphabet() ) ); other.pattern = NULL; } @@ -94,7 +94,7 @@ void RankedNonlinearPattern::setTree ( RankedNode pattern ) { delete this->pattern; this->pattern = std::move ( pattern ).plunder ( ); - if ( !this->pattern->attachTree ( this ) ) { + if ( !this->pattern->attachAlphabet ( & ( this->getAlphabet ( ) ) ) ) { delete this->pattern; throw TreeException ( "Input symbols not in the alphabet." ); } diff --git a/alib2data/src/tree/ranked/RankedPattern.cpp b/alib2data/src/tree/ranked/RankedPattern.cpp index d7e12ea90432fcdeb7f37b39eb38b0306ed5e5bd..8a1682c208b4a9985d5c5411222fb9d34a7129c2 100644 --- a/alib2data/src/tree/ranked/RankedPattern.cpp +++ b/alib2data/src/tree/ranked/RankedPattern.cpp @@ -46,11 +46,11 @@ RankedPattern::RankedPattern ( alphabet::RankedSymbol subtreeWildcard, RankedNod } RankedPattern::RankedPattern ( const RankedPattern & other ) : RankedPatternAlphabet ( other ), pattern ( other.pattern->clone ( ) ) { - this->pattern->attachTree ( this ); + this->pattern->attachAlphabet ( & ( this->getAlphabet() ) ); } RankedPattern::RankedPattern ( RankedPattern && other ) noexcept : RankedPatternAlphabet ( other ), pattern ( other.pattern ) { - this->pattern->attachTree ( this ); + this->pattern->attachAlphabet ( & ( this->getAlphabet() ) ); other.pattern = NULL; } @@ -95,7 +95,7 @@ void RankedPattern::setTree ( RankedNode pattern ) { delete this->pattern; this->pattern = std::move ( pattern ).plunder ( ); - if ( !this->pattern->attachTree ( this ) ) { + if ( !this->pattern->attachAlphabet ( & ( this->getAlphabet ( ) ) ) ) { delete this->pattern; throw TreeException ( "Input symbols not in the alphabet." ); } diff --git a/alib2data/src/tree/ranked/RankedTree.cpp b/alib2data/src/tree/ranked/RankedTree.cpp index 14b3d0f52048cb93e5ad8dd900fe628776f771e5..3efe5e8154fc552c4cda0ffd983d584f811fdc5e 100644 --- a/alib2data/src/tree/ranked/RankedTree.cpp +++ b/alib2data/src/tree/ranked/RankedTree.cpp @@ -25,34 +25,27 @@ namespace tree { -RankedTree::RankedTree ( const UnrankedTree & other ) { - this->tree = NULL; - RankedNode * element = other.getRoot ( ).cloneAsRanked ( ); - element->computeMinimalAlphabet ( alphabet ); - setTree ( std::move ( * element ) ); - delete element; +RankedTree::RankedTree ( const UnrankedTree & other ) : std::Components < RankedTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::set < alphabet::RankedSymbol > { } ), std::tuple < > ( ) ), tree ( other.getRoot ( ).cloneAsRanked ( ) ) { + tree->computeMinimalAlphabet ( accessComponent < GeneralAlphabet > ( ).get ( ) ); + + this->tree->attachAlphabet ( & ( this->getAlphabet ( ) ) ); } -RankedTree::RankedTree ( std::set < alphabet::RankedSymbol > alphabet, RankedNode tree ) { - this->alphabet = std::move ( alphabet ); - this->tree = NULL; +RankedTree::RankedTree ( std::set < alphabet::RankedSymbol > alphabet, RankedNode tree ) : std::Components < RankedTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::move ( alphabet ) ), std::tuple < > ( ) ), tree ( NULL ) { setTree ( std::move ( tree ) ); } -RankedTree::RankedTree ( RankedNode tree ) { - tree.computeMinimalAlphabet ( alphabet ); - this->tree = NULL; +RankedTree::RankedTree ( RankedNode tree ) : std::Components < RankedTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::set < alphabet::RankedSymbol > { } ), std::tuple < > ( ) ), tree ( NULL ) { + tree.computeMinimalAlphabet ( accessComponent < GeneralAlphabet > ( ).get ( ) ); setTree ( std::move ( tree ) ); } -RankedTree::RankedTree ( const RankedTree & other ) : tree ( other.tree->clone ( ) ) { - alphabet = other.alphabet; - this->tree->attachTree ( this ); +RankedTree::RankedTree ( const RankedTree & other ) : std::Components < RankedTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( other.getAlphabet ( ) ), std::tuple < > ( ) ), tree ( other.tree->clone ( ) ) { + this->tree->attachAlphabet ( & ( this->getAlphabet ( ) ) ); } -RankedTree::RankedTree ( RankedTree && other ) noexcept : tree ( other.tree ) { - alphabet = std::move ( other.alphabet ); - this->tree->attachTree ( this ); +RankedTree::RankedTree ( RankedTree && other ) noexcept : std::Components < RankedTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::move ( other.accessComponent < GeneralAlphabet > ( ).get ( ) ) ), std::tuple < > ( ) ), tree ( other.tree ) { + this->tree->attachAlphabet ( & ( this->getAlphabet ( ) ) ); other.tree = NULL; } @@ -75,7 +68,7 @@ RankedTree & RankedTree::operator =( const RankedTree & other ) { RankedTree & RankedTree::operator =( RankedTree && other ) noexcept { std::swap ( this->tree, other.tree ); - std::swap ( this->alphabet, other.alphabet ); + std::swap ( accessComponent < GeneralAlphabet > ( ).get ( ), other.accessComponent < GeneralAlphabet > ( ).get ( ) ); return * this; } @@ -96,19 +89,12 @@ void RankedTree::setTree ( RankedNode tree ) { delete this->tree; this->tree = std::move ( tree ).plunder ( ); - if ( !this->tree->attachTree ( this ) ) { + if ( !this->tree->attachAlphabet ( & ( this->getAlphabet ( ) ) ) ) { delete this->tree; throw TreeException ( "Input symbols not in the alphabet." ); } } -bool RankedTree::removeSymbolFromAlphabet ( const alphabet::RankedSymbol & symbol ) { - if ( this->tree->testSymbol ( symbol ) ) - throw TreeException ( "Input symbol \"" + ( std::string ) symbol + "\" is used." ); - - return alphabet.erase ( symbol ); -} - void RankedTree::operator >>( std::ostream & out ) const { out << "(RankedTree " << * ( this->tree ) << ")"; } @@ -118,7 +104,7 @@ int RankedTree::compare ( const RankedTree & other ) const { if ( res == 0 ) { std::compare < std::set < alphabet::RankedSymbol > > comp; - res = comp ( alphabet, other.alphabet ); + res = comp ( getAlphabet ( ), other.getAlphabet ( ) ); } return res; @@ -149,13 +135,31 @@ RankedTree RankedTree::parse ( std::deque < sax::Token >::iterator & input ) { void RankedTree::compose ( std::deque < sax::Token > & out ) const { out.emplace_back ( RankedTree::XML_TAG_NAME, sax::Token::TokenType::START_ELEMENT ); - TreeToXMLComposer::composeAlphabet ( out, alphabet ); + TreeToXMLComposer::composeAlphabet ( out, getAlphabet ( ) ); alib::xmlApi < RankedNode * >::compose ( out, tree ); out.emplace_back ( RankedTree::XML_TAG_NAME, sax::Token::TokenType::END_ELEMENT ); } } /* namespace tree */ +namespace std { + +template < > +bool tree::RankedTree::Component < tree::RankedTree, alphabet::RankedSymbol, tree::GeneralAlphabet >::used ( const alphabet::RankedSymbol & symbol ) const { + return static_cast < const tree::RankedTree * > ( this )->getRoot ( ).testSymbol ( symbol ); +} + +template < > +bool tree::RankedTree::Component < tree::RankedTree, alphabet::RankedSymbol, tree::GeneralAlphabet >::available ( const alphabet::RankedSymbol & ) const { + return true; +} + +template < > +void tree::RankedTree::Component < tree::RankedTree, alphabet::RankedSymbol, tree::GeneralAlphabet >::valid ( const alphabet::RankedSymbol & ) const { +} + +} /* namespace std */ + namespace alib { auto rankedTreeParserRegister = xmlApi < tree::Tree >::ParserRegister < tree::RankedTree > (); diff --git a/alib2data/src/tree/ranked/RankedTree.h b/alib2data/src/tree/ranked/RankedTree.h index 88c2b772781f13611826872f53d603163a3d8571..612167d3b9766e475c504a0ce6ea63bdc6822a74 100644 --- a/alib2data/src/tree/ranked/RankedTree.h +++ b/alib2data/src/tree/ranked/RankedTree.h @@ -8,24 +8,24 @@ #ifndef RANKED_TREE_H_ #define RANKED_TREE_H_ -#include <vector> -#include <list> #include <string> #include <set> +#include <core/components.hpp> + #include "RankedNode.h" #include "../RankedTreeBase.h" -#include "../common/RankedAlphabet.h" namespace tree { class RankedNode; class UnrankedTree; +class GeneralAlphabet; /** * Represents regular expression parsed from the XML. Regular expression is stored * as a tree of RegExpElement. */ -class RankedTree : public RankedTreeBase, public RankedAlphabet { +class RankedTree : public RankedTreeBase, public std::Components < RankedTree, alphabet::RankedSymbol, std::tuple < GeneralAlphabet >, std::tuple < > > { protected: RankedNode * tree; @@ -60,11 +60,11 @@ public: const RankedNode & getRoot ( ) const; const std::set < alphabet::RankedSymbol > & getAlphabet ( ) const { - return RankedAlphabet::getAlphabet ( ); + return accessComponent < GeneralAlphabet > ( ).get ( ); } void extendAlphabet ( const std::set < alphabet::RankedSymbol > & symbols ) { - addSymbolsToAlphabet ( symbols ); + accessComponent < GeneralAlphabet > ( ).add ( symbols ); } /** @@ -78,12 +78,6 @@ public: */ void setTree ( RankedNode tree ); - /** - * Removes symbol from the alphabet of symbol available in the regular expression - * @param symbol removed symbol from the alphabet - */ - bool removeSymbolFromAlphabet ( const alphabet::RankedSymbol & symbol ); - /** * Prints XML representation of the tree to the output stream. * @param out output stream to which print the tree diff --git a/alib2data/test-src/tree/TreeTest.cpp b/alib2data/test-src/tree/TreeTest.cpp index 059e6ba3751c6b399897d88c4f2039c4e6895dff..60a85c03d14abe2c6af2dcd4f0f87d623caf77dd 100644 --- a/alib2data/test-src/tree/TreeTest.cpp +++ b/alib2data/test-src/tree/TreeTest.cpp @@ -165,8 +165,6 @@ void TreeTest::testRankedTreeSymbolValidityCheck() { CPPUNIT_ASSERT_NO_THROW(tree -> getRoot().getChildren()[0] -> setSymbol(c)); CPPUNIT_ASSERT_THROW(tree -> getRoot().getChildren()[1] -> setSymbol(d), tree::TreeException); CPPUNIT_ASSERT_THROW(tree -> getRoot().getChildren()[0] -> setSymbol(a), tree::TreeException); - CPPUNIT_ASSERT_THROW(tree -> removeSymbolFromAlphabet(a), tree::TreeException); - CPPUNIT_ASSERT(tree -> removeSymbolFromAlphabet(e)); delete tree; }