From a0bc0384df612674eae04a880440b9b326b85e2b Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 10 Dec 2018 14:13:35 +0100
Subject: [PATCH] Abstraction: take out code applying parameters to function

---
 .../src/abstraction/AlgorithmAbstraction.hpp  |  2 +-
 .../src/abstraction/MemberAbstraction.hpp     |  2 +-
 .../abstraction/ValueOperationAbstraction.hpp | 54 +++++++------------
 .../src/abstraction/WrapperAbstraction.hpp    | 14 +----
 .../src/common/AbstractionHelpers.hpp         | 14 +++++
 5 files changed, 36 insertions(+), 50 deletions(-)

diff --git a/alib2abstraction/src/abstraction/AlgorithmAbstraction.hpp b/alib2abstraction/src/abstraction/AlgorithmAbstraction.hpp
index c237e4f3aa..5026b83459 100644
--- a/alib2abstraction/src/abstraction/AlgorithmAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/AlgorithmAbstraction.hpp
@@ -31,7 +31,7 @@ public:
 		if ( this->cached ( ) )
 			return true;
 
-		this->template run_helper < ParamTypes ... > ( m_callback, this->m_params, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+		this->template run_helper < ParamTypes ... > ( m_callback, this->m_params );
 		return true;
 	}
 
diff --git a/alib2abstraction/src/abstraction/MemberAbstraction.hpp b/alib2abstraction/src/abstraction/MemberAbstraction.hpp
index 6cb269921b..fe743cd8a3 100644
--- a/alib2abstraction/src/abstraction/MemberAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/MemberAbstraction.hpp
@@ -43,7 +43,7 @@ public:
 
 		std::get < 0 > ( params ) = std::make_pair ( reference, false );
 
-		this->template run_helper < typename std::remove_reference < ObjectType >::type *, ParamTypes ... > ( m_callback, params, std::make_index_sequence < sizeof ... ( ParamTypes ) + 1 > { } );
+		this->template run_helper < typename std::remove_reference < ObjectType >::type *, ParamTypes ... > ( m_callback, params );
 		return true;
 	}
 
diff --git a/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp b/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp
index 3e48214459..52173501d1 100644
--- a/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp
@@ -37,13 +37,10 @@ protected:
 	mutable ext::variant < void, ReturnType > m_data;
 
 public:
-	template < typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
+	template < typename ... ParamTypes, typename Callable >
+	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
 		if ( ! isReady ( ) )
-			m_data = callback ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( inputs ).first, std::get < Indexes > ( inputs ).second ) ... );
+			m_data = abstraction::apply < ParamTypes ... > ( callback, inputs );
 	}
 
 	virtual bool isReady ( ) const override {
@@ -80,13 +77,10 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
 
 public:
-	template < typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
+	template < typename ... ParamTypes, typename Callable >
+	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
 		if ( ! isReady ( ) )
-			m_data = std::reference_wrapper < ReturnType > ( callback ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( inputs ).first, std::get < Indexes > ( inputs ).second ) ... ) );
+			m_data = std::reference_wrapper < ReturnType > ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
 	}
 
 	virtual bool isReady ( ) const override {
@@ -119,13 +113,10 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
 
 public:
-	template < typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
+	template < typename ... ParamTypes, typename Callable >
+	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
 		if ( ! isReady ( ) )
-			m_data = std::reference_wrapper < const ReturnType > ( callback ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( inputs ).first, std::get < Indexes > ( inputs ).second ) ... ) );
+			m_data = std::reference_wrapper < const ReturnType > ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
 	}
 
 	virtual bool isReady ( ) const override {
@@ -162,13 +153,10 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
 
 public:
-	template < typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
+	template < typename ... ParamTypes, typename Callable >
+	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
 		if ( ! isReady ( ) ) {
-			ReturnType && res = callback ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( inputs ).first, std::get < Indexes > ( inputs ).second ) ... );
+			ReturnType && res = abstraction::apply < ParamTypes ... > ( callback, inputs );
 			m_data = std::reference_wrapper < ReturnType > ( res );
 		}
 	}
@@ -203,13 +191,10 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
 
 public:
-	template < typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
+	template < typename ... ParamTypes, typename Callable >
+	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
 		if ( ! isReady ( ) ) {
-			const ReturnType && res = callback ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( inputs ).first, std::get < Indexes > ( inputs ).second ) ... );
+			const ReturnType && res = abstraction::apply < ParamTypes ... > ( callback, inputs );
 			m_data = std::reference_wrapper < const ReturnType > ( res );
 		}
 	}
@@ -237,12 +222,9 @@ public:
 template < >
 class ValueOperationAbstraction < void > : public OperationAbstraction {
 public:
-	template < typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		callback ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( inputs ).first, std::get < Indexes > ( inputs ).second ) ... );
+	template < typename ... ParamTypes, typename Callable >
+	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
+		abstraction::apply < ParamTypes ... > ( callback, inputs );
 	}
 
 	virtual bool isReady ( ) const override {
diff --git a/alib2abstraction/src/abstraction/WrapperAbstraction.hpp b/alib2abstraction/src/abstraction/WrapperAbstraction.hpp
index 094e8ed44e..3634fcc7a1 100644
--- a/alib2abstraction/src/abstraction/WrapperAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/WrapperAbstraction.hpp
@@ -72,16 +72,6 @@ public:
 		return true;
 	}
 
-
-protected:
-	template < size_t ... Indexes >
-	inline void finder_helper ( const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( Indexes ) > & params, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) params;
-
-		m_data = m_WrapperFinder ( abstraction::retrieveValue < ParamTypes > ( std::get < Indexes > ( params ).first, std::get < Indexes > ( params ).second ) ... );
-	}
-
 public:
 	virtual bool eval ( ) override {
 		if ( ! inputsAttached ( ) )
@@ -129,7 +119,7 @@ public:
 
 	virtual bool run ( ) override {
 		if ( this->m_data.template is < void > ( ) )
-			this->finder_helper ( this->m_params, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+			this->m_data = abstraction::apply < ParamTypes ... > ( this->m_WrapperFinder, this->m_params );
 
 		std::shared_ptr < OperationAbstraction > & abstraction = this->m_data.template get < std::shared_ptr < OperationAbstraction > > ( );
 		if ( abstraction->getReturnTypeIndex ( ) != this->getReturnTypeIndex ( ) )
@@ -162,7 +152,7 @@ public:
 
 	virtual bool run ( ) override {
 		if ( this->m_data.template is < void > ( ) )
-			this->finder_helper ( this->m_params, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+			this->m_data = abstraction::apply < ParamTypes ... > ( this->m_WrapperFinder, this->m_params );
 
 		std::shared_ptr < OperationAbstraction > & abstraction = this->m_data.template get < std::shared_ptr < OperationAbstraction > > ( );
 		for ( unsigned index = 0; index < sizeof ... ( ParamTypes ); ++ index )
diff --git a/alib2abstraction/src/common/AbstractionHelpers.hpp b/alib2abstraction/src/common/AbstractionHelpers.hpp
index 5e27a2fb7b..7fca861d91 100644
--- a/alib2abstraction/src/common/AbstractionHelpers.hpp
+++ b/alib2abstraction/src/common/AbstractionHelpers.hpp
@@ -20,6 +20,20 @@ ParamType retrieveValue ( const std::shared_ptr < OperationAbstraction > & param
 	return translateParam < ParamType > ( param )->getValue ( move );
 }
 
+namespace detail {
+
+template < class ... ParamTypes, class F, class Tuple, std::size_t... I >
+constexpr decltype ( auto ) apply_impl ( F && f, Tuple && t, std::index_sequence < I ... > ) {
+	return std::invoke ( std::forward < F > ( f ), abstraction::retrieveValue < ParamTypes > ( std::get < I > ( std::forward < Tuple > ( t ) ).first, std::get < I > ( std::forward < Tuple > ( t ) ).second ) ... );
+}
+
+}  // namespace detail
+
+template < class ... ParamTypes, class F, class Tuple >
+constexpr decltype ( auto ) apply ( F && f, Tuple && t ) {
+	return detail::apply_impl < ParamTypes ... > ( std::forward < F > ( f ), std::forward < Tuple > ( t ), std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+}
+
 template < class ... Params >
 struct CheckInput;
 
-- 
GitLab