From f6688868bffd39bdd07f6dba8b62b61817acf0c8 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sat, 8 Dec 2018 23:06:23 +0100
Subject: [PATCH] Abstraction: redesign member call

---
 .../src/abstraction/MemberAbstraction.hpp     | 14 ++++-
 .../src/abstraction/ReferenceAbstraction.hpp  | 34 +++++++++++
 .../abstraction/ValueOperationAbstraction.hpp | 57 -------------------
 3 files changed, 47 insertions(+), 58 deletions(-)
 create mode 100644 alib2abstraction/src/abstraction/ReferenceAbstraction.hpp

diff --git a/alib2abstraction/src/abstraction/MemberAbstraction.hpp b/alib2abstraction/src/abstraction/MemberAbstraction.hpp
index 3dc85c6ecb..6cb269921b 100644
--- a/alib2abstraction/src/abstraction/MemberAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/MemberAbstraction.hpp
@@ -11,6 +11,7 @@
 #include <alib/memory>
 
 #include <abstraction/NaryOperationAbstraction.hpp>
+#include <abstraction/ReferenceAbstraction.hpp>
 
 #include <registry/Registry.h>
 
@@ -31,7 +32,18 @@ public:
 		if ( this->cached ( ) )
 			return true;
 
-		this->template member_run_helper < ObjectType, ParamTypes ... > ( m_callback, this->m_params, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+		ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) + 1 > params = this->m_params;
+
+		std::shared_ptr < OperationAbstraction > reference = std::make_shared < ReferenceAbstraction < typename std::remove_reference < ObjectType >::type > > ( );
+		if ( ! reference->attachInput ( std::get < 0 > ( this->m_params ).first, 0, std::get < 0 > ( this->m_params ).second, true ) )
+			throw std::invalid_argument ( "Can't bind the object of call to member." );
+
+		if ( ! reference->eval ( ) )
+			throw std::invalid_argument ( "Eval of object of call to member falsed." );
+
+		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 > { } );
 		return true;
 	}
 
diff --git a/alib2abstraction/src/abstraction/ReferenceAbstraction.hpp b/alib2abstraction/src/abstraction/ReferenceAbstraction.hpp
new file mode 100644
index 0000000000..0fadebed6b
--- /dev/null
+++ b/alib2abstraction/src/abstraction/ReferenceAbstraction.hpp
@@ -0,0 +1,34 @@
+/*
+ * ReferenceAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _REFERENCE_ABSTRACTION_HPP_
+#define _REFERENCE_ABSTRACTION_HPP_
+
+#include <abstraction/UnaryOperationAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Type >
+class ReferenceAbstraction : public UnaryOperationAbstraction < Type *, Type & > {
+public:
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		std::pair < std::shared_ptr < OperationAbstraction >, bool > & param = std::get < 0 > ( this->m_params );
+		this->m_data = & retrieveValue < Type & > ( param.first, param.second );
+
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _REFERENCE_ABSTRACTION_HPP_ */
diff --git a/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp b/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp
index d10a33fe31..3e48214459 100644
--- a/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/ValueOperationAbstraction.hpp
@@ -37,15 +37,6 @@ protected:
 	mutable ext::variant < void, ReturnType > m_data;
 
 public:
-	template < typename Object, typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void member_run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, 1 + sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		if ( ! isReady ( ) )
-			m_data = callback ( & abstraction::retrieveValue < Object > ( std::get < 0 > ( inputs ).first, std::get < 0 > ( inputs ).second ), abstraction::retrieveValue < ParamTypes > ( std::get < Indexes + 1 > ( inputs ).first, std::get < Indexes + 1 > ( inputs ).second ) ... );
-	}
-
 	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 */
@@ -89,15 +80,6 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
 
 public:
-	template < typename Object, typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void member_run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, 1 + sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		if ( ! isReady ( ) )
-			m_data = std::reference_wrapper < ReturnType > ( callback ( & abstraction::retrieveValue < Object > ( std::get < 0 > ( inputs ).first, std::get < 0 > ( inputs ).second ), abstraction::retrieveValue < ParamTypes > ( std::get < Indexes + 1 > ( inputs ).first, std::get < Indexes + 1 > ( inputs ).second ) ... ) );
-	}
-
 	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 */
@@ -137,15 +119,6 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
 
 public:
-	template < typename Object, typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void member_run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, 1 + sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		if ( ! isReady ( ) )
-			m_data = std::reference_wrapper < const ReturnType > ( callback ( & abstraction::retrieveValue < Object > ( std::get < 0 > ( inputs ).first, std::get < 0 > ( inputs ).second ), abstraction::retrieveValue < ParamTypes > ( std::get < Indexes + 1 > ( inputs ).first, std::get < Indexes + 1 > ( inputs ).second ) ... ) );
-	}
-
 	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 */
@@ -189,17 +162,6 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
 
 public:
-	template < typename Object, typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void member_run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, 1 + sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		if ( ! isReady ( ) ) {
-			ReturnType && res = callback ( & abstraction::retrieveValue < Object > ( std::get < 0 > ( inputs ).first, std::get < 0 > ( inputs ).second ), abstraction::retrieveValue < ParamTypes > ( std::get < Indexes + 1 > ( inputs ).first, std::get < Indexes + 1 > ( inputs ).second ) ... );
-			m_data = std::reference_wrapper < ReturnType > ( res );
-		}
-	}
-
 	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 */
@@ -241,17 +203,6 @@ protected:
 	mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
 
 public:
-	template < typename Object, typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void member_run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, 1 + sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		if ( ! isReady ( ) ) {
-			const ReturnType && res = callback ( & abstraction::retrieveValue < Object > ( std::get < 0 > ( inputs ).first, std::get < 0 > ( inputs ).second ), abstraction::retrieveValue < ParamTypes > ( std::get < Indexes + 1 > ( inputs ).first, std::get < Indexes + 1 > ( inputs ).second ) ... );
-			m_data = std::reference_wrapper < const ReturnType > ( res );
-		}
-	}
-
 	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 */
@@ -286,14 +237,6 @@ public:
 template < >
 class ValueOperationAbstraction < void > : public OperationAbstraction {
 public:
-	template < typename Object, typename ... ParamTypes, typename Callable, size_t ... Indexes >
-	inline void member_run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, 1 + sizeof ... ( Indexes ) > & inputs, std::index_sequence < Indexes ... > ) {
-		/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
-		( void ) inputs;
-
-		callback ( & abstraction::retrieveValue < Object > ( std::get < 0 > ( inputs ).first, std::get < 0 > ( inputs ).second ), abstraction::retrieveValue < ParamTypes > ( std::get < Indexes + 1 > ( inputs ).first, std::get < Indexes + 1 > ( inputs ).second ) ... );
-	}
-
 	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 */
-- 
GitLab