diff --git a/alib2common/src/core/visitor.hpp b/alib2common/src/core/visitor.hpp index b165d59e89f887efbe786cf8aa9a01e8ff145484..df616a084eecb3dc250e5e272e3bc1af3c0ba78e 100644 --- a/alib2common/src/core/visitor.hpp +++ b/alib2common/src/core/visitor.hpp @@ -53,7 +53,6 @@ public: new ( & result ) ReturnType ( Visitor::visit ( inherit, std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); } - /** * \brief * Call method to the visitors visit method. The actuall class of visited object is already evaluated here. @@ -76,7 +75,6 @@ public: new ( & result ) ReturnType ( Visitor::visit ( inherit, std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); } - /** * \brief * Call method to the visitors visit method. The actuall class of visited object is already evaluated here. @@ -88,6 +86,28 @@ public: ReturnType ( Visitor::visit ( inherit, std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); } + /** + * \brief + * Call method to the visitors visit method. The actuall class of visited object is already evaluated here. + * + * This call method is enabled if the return type is not void. + */ + template < class Inherit, size_t ... Indexes, class ReturnType2 = ReturnType > + void call ( Inherit && inherit, std::index_sequence < Indexes ... >, typename std::enable_if < !std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) { + new ( & result ) ReturnType ( Visitor::visit ( std::move ( inherit ), std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); + } + + /** + * \brief + * Call method to the visitors visit method. The actuall class of visited object is already evaluated here. + * + * This call method is enabled if the return type is void. + */ + template < class Inherit, size_t ... Indexes, class ReturnType2 = ReturnType > + void call ( Inherit && inherit, std::index_sequence < Indexes ... >, typename std::enable_if < std::is_void < ReturnType2 >::value && std::is_same < ReturnType, ReturnType2 >::value >::type * = 0 ) { + ReturnType ( Visitor::visit ( std::move ( inherit ), std::forward < Params > ( std::get < Indexes > ( m_params ) ) ... ) ); + } + /** * \brief * Visit result getter. diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h index de8252dafafe347f48876305dd86d83f887879a7..60c2bd226fc0de40b4d60818b31cdc4875c9c4a5 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h @@ -47,10 +47,17 @@ class UnboundedRegExpAlternation : public UnboundedRegExpElement < SymbolType >, /** * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const */ - void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const override { + void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const & override { visitor.visit ( * this ); } + /** + * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const + */ + void accept ( typename UnboundedRegExpElement < SymbolType >::RvalueVisitor & visitor ) && override { + visitor.visit ( std::move ( * this ) ); + } + public: /** * \brief Creates a new instance of the alternation node. By default it is semantically equivalent to empty regular expression. diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h index 34716ca138224b0dea164bcaf00e79acbff1fef9..06b71fce74ac27cb445c50ececcbfff2c99f89fb 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h @@ -47,10 +47,17 @@ class UnboundedRegExpConcatenation : public UnboundedRegExpElement < SymbolType /** * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const */ - void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const override { + void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const & override { visitor.visit ( * this ); } + /** + * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const + */ + void accept ( typename UnboundedRegExpElement < SymbolType >::RvalueVisitor & visitor ) && override { + visitor.visit ( std::move ( * this ) ); + } + public: /** * \brief Creates a new instance of the concatenation node. By default it is semantically equivalent to epsilon. diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h index 6dcf1ffc9f00cba0983cc25efe1b277640c7d37d..664e67d6371d271e9975b62a2c3db23dba4c7115 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h @@ -76,6 +76,19 @@ protected: virtual void visit ( const UnboundedRegExpEpsilon < SymbolType > & ) = 0; }; + /** + * Visitor interface of the element. + */ + class RvalueVisitor { + public: + virtual void visit ( UnboundedRegExpAlternation < SymbolType > && ) = 0; + virtual void visit ( UnboundedRegExpConcatenation < SymbolType > && ) = 0; + virtual void visit ( UnboundedRegExpIteration < SymbolType > && ) = 0; + virtual void visit ( UnboundedRegExpSymbol < SymbolType > && ) = 0; + virtual void visit ( UnboundedRegExpEmpty < SymbolType > && ) = 0; + virtual void visit ( UnboundedRegExpEpsilon < SymbolType > && ) = 0; + }; + /** * Helper class interconnecting the visitor interface and visitor core logic. * @@ -134,12 +147,77 @@ protected: } }; + /** + * Helper class interconnecting the visitor interface and visitor core logic. + * + * \tparam ReturnType the return type of the result of the visit + * \tparam Visitorr the type of the actuall visitor + * \tparam Params ... types of data passed with the visitor call + */ + template < class ReturnType, class Visitorr, class ... Params > + class RvalueVisitorContext : public core::VisitorContextAux < ReturnType, Visitorr, Params ... >, public UnboundedRegExpElement::RvalueVisitor { + public: + /** + * Inherited constructor. + */ + using core::VisitorContextAux < ReturnType, Visitorr, Params ... >::VisitorContextAux; + + /** + * Method passing the visit call to the visitor core logic. + */ + void visit ( UnboundedRegExpAlternation < SymbolType > && inherit ) override { + this->call ( std::move ( inherit ), std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + /** + * Method passing the visit call to the visitor core logic. + */ + void visit ( UnboundedRegExpConcatenation < SymbolType > && inherit ) override { + this->call ( std::move ( inherit ), std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + /** + * Method passing the visit call to the visitor core logic. + */ + void visit ( UnboundedRegExpIteration < SymbolType > && inherit ) override { + this->call ( std::move ( inherit ), std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + /** + * Method passing the visit call to the visitor core logic. + */ + void visit ( UnboundedRegExpSymbol < SymbolType > && inherit ) override { + this->call ( std::move ( inherit ), std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + /** + * Method passing the visit call to the visitor core logic. + */ + void visit ( UnboundedRegExpEmpty < SymbolType > && inherit ) override { + this->call ( std::move ( inherit ), std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + /** + * Method passing the visit call to the visitor core logic. + */ + void visit ( UnboundedRegExpEpsilon < SymbolType > && inherit ) override { + this->call ( std::move ( inherit ), std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + }; + + /** + * \brief Accept method of the visitor pattern. This is where the actual type of this object is evaluated. + * + * \param visitor the accepted visitor. + */ + virtual void accept ( UnboundedRegExpElement::Visitor & visitor ) const & = 0; + /** * \brief Accept method of the visitor pattern. This is where the actual type of this object is evaluated. * * \param visitor the accepted visitor. */ - virtual void accept ( UnboundedRegExpElement::Visitor & visitor ) const = 0; + virtual void accept ( UnboundedRegExpElement::RvalueVisitor & visitor ) && = 0; public: virtual UnboundedRegExpElement < SymbolType > * clone ( ) const & = 0; @@ -158,12 +236,30 @@ public: * \return result of the visit */ template < class ReturnType, class Visitorr, class ... Params > - ReturnType accept ( Params && ... params ) const { + ReturnType accept ( Params && ... params ) const & { VisitorContext < ReturnType, Visitorr, Params ... > context ( std::forward < Params > ( params ) ... ); accept ( context ); return context.getResult ( ); } + /** + * Visitor interface method. + * + * \tparam ReturnType the return type of the result of the visit + * \tparam Visitorr the type of the actuall visitor + * \tparam Params ... types of data passed with the visitor call + * + * \params params ... Additional params passed to visited nodes + * + * \return result of the visit + */ + template < class ReturnType, class Visitorr, class ... Params > + ReturnType accept ( Params && ... params ) && { + RvalueVisitorContext < ReturnType, Visitorr, Params ... > context ( std::forward < Params > ( params ) ... ); + std::move ( * this ).accept ( context ); + return context.getResult ( ); + } + /** * Creates copy of the element. * diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h index 0cb0819554e4099018081b7532de1d3b45a18e59..334db8e0eadbd348a68fee0b8a5ee23a1b97f7b2 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h @@ -44,10 +44,17 @@ class UnboundedRegExpEmpty : public UnboundedRegExpElement < SymbolType >, publi /** * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const */ - void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const override { + void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const & override { visitor.visit ( * this ); } + /** + * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const + */ + void accept ( typename UnboundedRegExpElement < SymbolType >::RvalueVisitor & visitor ) && override { + visitor.visit ( std::move ( * this ) ); + } + public: /** * \brief Creates a new instance of the empty node. diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h index f4086c6fddb76f409b492413b731e2df44f28f31..de1dc77c7e7077db1435fcfa20c9d40ae5f3a48a 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h @@ -44,10 +44,17 @@ class UnboundedRegExpEpsilon : public UnboundedRegExpElement < SymbolType >, pub /** * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const */ - void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const override { + void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const & override { visitor.visit ( * this ); } + /** + * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const + */ + void accept ( typename UnboundedRegExpElement < SymbolType >::RvalueVisitor & visitor ) && override { + visitor.visit ( std::move ( * this ) ); + } + public: /** * \brief Creates a new instance of the epsilon node. diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h index cc9114c657a0da10972f58f1d45d179d397f8ef4..278dd89a02ed182dfb64985552c56f60e6f359c3 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h @@ -46,10 +46,17 @@ class UnboundedRegExpIteration : public UnboundedRegExpElement < SymbolType >, p /** * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const */ - void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const override { + void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const & override { visitor.visit ( * this ); } + /** + * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const + */ + void accept ( typename UnboundedRegExpElement < SymbolType >::RvalueVisitor & visitor ) && override { + visitor.visit ( std::move ( * this ) ); + } + public: /** * \brief Creates a new instance of the iteration node with explicit iterated element diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h index bef1d33388379c3ba41fc5f8b69dc788e255c5e7..ad25f64ae5ce42985f99b52ee958ff2b40a596fc 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h @@ -50,10 +50,17 @@ class UnboundedRegExpSymbol : public UnboundedRegExpElement < SymbolType >, publ /** * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const */ - void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const override { + void accept ( typename UnboundedRegExpElement < SymbolType >::Visitor & visitor ) const & override { visitor.visit ( * this ); } + /** + * @copydoc regexp::UnboundedRegExpElement < SymbolType >::accept ( ) const + */ + void accept ( typename UnboundedRegExpElement < SymbolType >::RvalueVisitor & visitor ) && override { + visitor.visit ( std::move ( * this ) ); + } + public: /** * \brief Creates a new instance of the symbol node using the actual symbol to represent.