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