From 243f0cf3449fb69335e6cfba5aa1c32a9b093359 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <jan.travnicek@.fit.cvut.cz> Date: Thu, 28 Feb 2019 15:47:44 +0100 Subject: [PATCH] add rvalued visitor to unbounded regexp --- alib2common/src/core/visitor.hpp | 24 ++++- .../unbounded/UnboundedRegExpAlternation.h | 9 +- .../unbounded/UnboundedRegExpConcatenation.h | 9 +- .../regexp/unbounded/UnboundedRegExpElement.h | 100 +++++++++++++++++- .../regexp/unbounded/UnboundedRegExpEmpty.h | 9 +- .../regexp/unbounded/UnboundedRegExpEpsilon.h | 9 +- .../unbounded/UnboundedRegExpIteration.h | 9 +- .../regexp/unbounded/UnboundedRegExpSymbol.h | 9 +- 8 files changed, 168 insertions(+), 10 deletions(-) diff --git a/alib2common/src/core/visitor.hpp b/alib2common/src/core/visitor.hpp index b165d59e89..df616a084e 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 de8252dafa..60c2bd226f 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 34716ca138..06b71fce74 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 6dcf1ffc9f..664e67d637 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 0cb0819554..334db8e0ea 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 f4086c6fdd..de1dc77c7e 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 cc9114c657..278dd89a02 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 bef1d33388..ad25f64ae5 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. -- GitLab