From b9b1f2dcfb96fd7c635e91a365c8f67a9c34bf73 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 20 Aug 2017 23:20:14 +0200
Subject: [PATCH] qualified type aware abstraction

---
 alib2cli/test-src/cli/CliTest.cpp             |   4 +-
 .../src/abstraction/AlgorithmAbstraction.hpp  | 109 ++------
 .../src/abstraction/CastAbstraction.hpp       |   2 +-
 alib2common/src/abstraction/CastRegistry.hpp  |   4 +-
 .../src/abstraction/DowncastAbstraction.hpp   |   2 +-
 .../src/abstraction/DowncastRegistry.hpp      |   2 +-
 .../abstraction/ImmediateValueAbstraction.hpp |   2 +-
 .../src/abstraction/NormalizeAbstraction.hpp  |   2 +-
 .../NullaryOperationAbstraction.hpp           |   6 +-
 .../src/abstraction/OperationAbstraction.hpp  |   2 +-
 .../src/abstraction/ResultClassSelector.hpp   |  29 --
 .../abstraction/UnaryOperationAbstraction.hpp |  12 +-
 .../abstraction/ValueOperationAbstraction.hpp | 258 +++++++++++++++++-
 .../abstraction/ValuePrinterAbstraction.hpp   |   2 +-
 .../src/abstraction/ValuePrinterRegistry.hpp  |   2 +-
 .../abstraction/VoidOperationAbstraction.hpp  |  43 ---
 .../abstraction/XmlFileWriterAbstraction.hpp  |   2 +-
 .../src/abstraction/XmlFileWriterRegistry.hpp |   2 +-
 .../src/abstraction/XmlParserAbstraction.hpp  |   4 +-
 19 files changed, 293 insertions(+), 196 deletions(-)
 delete mode 100644 alib2common/src/abstraction/ResultClassSelector.hpp
 delete mode 100644 alib2common/src/abstraction/VoidOperationAbstraction.hpp

diff --git a/alib2cli/test-src/cli/CliTest.cpp b/alib2cli/test-src/cli/CliTest.cpp
index f805202c9b..532d8340c5 100644
--- a/alib2cli/test-src/cli/CliTest.cpp
+++ b/alib2cli/test-src/cli/CliTest.cpp
@@ -37,11 +37,11 @@ public:
 
 class Add {
 public:
-	static int add ( int a, int b ) {
+	static int add ( int a, const int & b ) {
 		return a + b;
 	}
 
-	static int add2 ( primitive::Integer a, int b ) {
+	static int add2 ( const primitive::Integer & a, int b ) {
 		return a.getData ( ) + b;
 	}
 };
diff --git a/alib2common/src/abstraction/AlgorithmAbstraction.hpp b/alib2common/src/abstraction/AlgorithmAbstraction.hpp
index 16b5b2ca32..cc01e984ef 100644
--- a/alib2common/src/abstraction/AlgorithmAbstraction.hpp
+++ b/alib2common/src/abstraction/AlgorithmAbstraction.hpp
@@ -8,7 +8,7 @@
 #ifndef _ALGORITHM_ABSTRACTION_HPP_
 #define _ALGORITHM_ABSTRACTION_HPP_
 
-#include <abstraction/ResultClassSelector.hpp>
+#include <abstraction/ValueOperationAbstraction.hpp>
 #include <tuple>
 #include <memory>
 #include <abstraction/Registry.h>
@@ -16,48 +16,10 @@
 namespace abstraction {
 
 template < class ReturnType, class ... ParamTypes >
-class Callback {
-	std::function < ReturnType ( ParamTypes ... ) > m_callback;
-
-public:
-	Callback ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
-	}
-
-	ReturnType * operator ( ) ( ParamTypes ... params ) {
-		return new ReturnType ( m_callback ( std::forward < ParamTypes > ( params ) ... ) );
-	}
-};
-
-template < class ReturnType, class ... ParamTypes >
-class Callback < ReturnType *, ParamTypes ... > {
-	std::function < ReturnType * ( ParamTypes ... ) > m_callback;
+class AlgorithmAbstraction : public ValueOperationAbstraction < ReturnType > {
+	ext::tuple < std::shared_ptr < ValueProvider < ParamTypes > > ... > inputs;
 
-public:
-	Callback ( std::function < ReturnType * ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
-	}
-
-	ReturnType * operator ( ) ( ParamTypes ... params ) {
-		return m_callback ( std::forward < ParamTypes > ( params ) ... );
-	}
-};
-
-template < class ... ParamTypes >
-class Callback < void, ParamTypes ... > {
-	std::function < void ( ParamTypes ... ) > m_callback;
-
-public:
-	Callback ( std::function < void ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
-	}
-
-	void operator ( ) ( ParamTypes ... params ) {
-		m_callback ( std::forward < ParamTypes > ( params ) ... );
-	}
-};
-
-template < class ReturnType, class ... ParamTypes >
-class AlgorithmAbstractionBase : public ResultClassSelector < ReturnType >::OutputClass {
-protected:
-	ext::tuple < std::shared_ptr < ValueOperationAbstraction < typename std::decay < ParamTypes >::type > > ... > inputs;
+	std::function < ReturnType ( ParamTypes ... ) > m_callback;
 
 	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) override {
 		auto attachCallback = [ & ] ( auto & param ) {
@@ -75,18 +37,18 @@ protected:
 		return ext::call_on_nth < bool > ( inputs, index, attachCallback );
 	}
 
-	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) override {
-		bool res = false;
-		ext::foreach ( inputs, [ & ] ( auto & param ) {
-				if ( param == input ) {
-					param = nullptr;
-					res = true;
-				}
-			} );
-		return res;
+	virtual bool detachInput ( unsigned index ) override {
+		auto detachCallback = [ & ] ( auto & param ) {
+			param = nullptr;
+			return true;
+		};
+		return ext::call_on_nth < bool > ( inputs, index, detachCallback );
 	}
 
 public:
+	AlgorithmAbstraction ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
+	}
+
 	virtual bool inputsReady ( ) const override {
 		auto readyCallback = [ ] ( const auto & param ) {
 			return ( bool ) param && param->isReady ( );
@@ -120,27 +82,6 @@ public:
 		return this->run ( );
 	}
 
-	virtual unsigned numberOfParams ( ) const override {
-		return sizeof ... ( ParamTypes );
-	}
-
-	virtual ext::type_index getParamTypeIndex ( unsigned index ) const override {
-		auto callback = [ & ] ( auto & param ) {
-			return ext::type_index ( typeid ( typename std::decay < decltype ( param ) >::type::element_type::return_type ) );
-		};
-		return ext::call_on_nth < ext::type_index > ( inputs, index, callback );
-	}
-
-};
-
-template < class ReturnType, class ... ParamTypes >
-class AlgorithmAbstraction : public AlgorithmAbstractionBase < ReturnType, ParamTypes ... > {
-	Callback < ReturnType, ParamTypes ... > m_callback;
-
-public:
-	AlgorithmAbstraction ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
-	}
-
 	virtual bool run ( ) override {
 		if ( ! this->inputsReady ( ) )
 			return false;
@@ -152,25 +93,15 @@ public:
 		return true;
 	}
 
-};
-
-template < class ReturnType, class ... ParamTypes >
-class AlgorithmAbstraction < ReturnType *, ParamTypes ... > : public AlgorithmAbstractionBase < ReturnType, ParamTypes ... > {
-	Callback < ReturnType *, ParamTypes ... > m_callback;
-
-public:
-	AlgorithmAbstraction ( std::function < ReturnType * ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
+	virtual unsigned numberOfParams ( ) const override {
+		return sizeof ... ( ParamTypes );
 	}
 
-	virtual bool run ( ) override {
-		if ( ! this->inputsReady ( ) )
-			return false;
-
-		if ( this->cached ( ) )
-			return true;
-
-		this->run_helper ( m_callback, this->inputs, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
-		return true;
+	virtual ext::type_index getParamTypeIndex ( unsigned index ) const override {
+		auto callback = [ & ] ( auto & param ) {
+			return ext::type_index ( typeid ( typename std::decay < decltype ( param ) >::type::element_type::return_type ) );
+		};
+		return ext::call_on_nth < ext::type_index > ( inputs, index, callback );
 	}
 
 };
diff --git a/alib2common/src/abstraction/CastAbstraction.hpp b/alib2common/src/abstraction/CastAbstraction.hpp
index 87ce0eb5cb..a92b875d97 100644
--- a/alib2common/src/abstraction/CastAbstraction.hpp
+++ b/alib2common/src/abstraction/CastAbstraction.hpp
@@ -26,7 +26,7 @@ public:
 		if ( this->cached ( ) )
 			return true;
 
-		this->m_data = std::unique_ptr < ReturnType > ( new ReturnType ( this->m_param->getData ( ) ) );
+		this->m_data = ReturnType ( this->m_param->getConstValueReference ( ) );
 
 		return true;
 	}
diff --git a/alib2common/src/abstraction/CastRegistry.hpp b/alib2common/src/abstraction/CastRegistry.hpp
index 06b2870fa8..5b6d34135e 100644
--- a/alib2common/src/abstraction/CastRegistry.hpp
+++ b/alib2common/src/abstraction/CastRegistry.hpp
@@ -193,12 +193,12 @@ namespace abstraction {
 
 template < class Return, class Param >
 std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::DefaultEntryImpl < Return, Param >::getAbstraction ( ) const {
-	return std::make_shared < abstraction::CastAbstraction < Return, Param > > ( );
+	return std::make_shared < abstraction::CastAbstraction < Return, const Param & > > ( );
 }
 
 template < class Return, class Param >
 std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::AlgorithmEntryImpl < Return, Param >::getAbstraction ( ) const {
-	return std::make_shared < abstraction::AlgorithmAbstraction < Return, Param > > ( m_callback );
+	return std::make_shared < abstraction::AlgorithmAbstraction < Return, const Param & > > ( m_callback );
 }
 
 } /* namespace abstraction */
diff --git a/alib2common/src/abstraction/DowncastAbstraction.hpp b/alib2common/src/abstraction/DowncastAbstraction.hpp
index 71504db528..386c7ea22d 100644
--- a/alib2common/src/abstraction/DowncastAbstraction.hpp
+++ b/alib2common/src/abstraction/DowncastAbstraction.hpp
@@ -26,7 +26,7 @@ public:
 		if ( this->cached ( ) )
 			return true;
 
-		this->m_data = std::unique_ptr < ConcreteType > ( static_cast < ConcreteType * > ( this->m_param->getData ( ).clone ( ) ) );
+		this->m_data = ConcreteType ( static_cast < const ConcreteType & > ( this->m_param->getConstValueReference ( ) ) );
 
 		return true;
 	}
diff --git a/alib2common/src/abstraction/DowncastRegistry.hpp b/alib2common/src/abstraction/DowncastRegistry.hpp
index 7b7aaf3e7b..25e4621ecb 100644
--- a/alib2common/src/abstraction/DowncastRegistry.hpp
+++ b/alib2common/src/abstraction/DowncastRegistry.hpp
@@ -63,7 +63,7 @@ namespace abstraction {
 
 template < class ConcreteType, class BaseType >
 std::shared_ptr < abstraction::OperationAbstraction > DowncastRegistry::EntryImpl < ConcreteType, BaseType >::getAbstraction ( ) const {
-	return std::make_shared < DowncastAbstraction < ConcreteType, BaseType > > ( );
+	return std::make_shared < DowncastAbstraction < ConcreteType, const BaseType & > > ( );
 }
 
 } /* namespace abstraction */
diff --git a/alib2common/src/abstraction/ImmediateValueAbstraction.hpp b/alib2common/src/abstraction/ImmediateValueAbstraction.hpp
index 286c7947b0..8db823793f 100644
--- a/alib2common/src/abstraction/ImmediateValueAbstraction.hpp
+++ b/alib2common/src/abstraction/ImmediateValueAbstraction.hpp
@@ -17,7 +17,7 @@ template < class ReturnType >
 class ImmediateValueAbstraction : public NullaryOperationAbstraction < ReturnType > {
 public:
 	ImmediateValueAbstraction ( ReturnType result ) {
-		this->m_data = std::unique_ptr < ReturnType > ( new ReturnType ( result ) );
+		this->m_data = ReturnType ( result );
 	}
 
 	virtual bool run ( ) override {
diff --git a/alib2common/src/abstraction/NormalizeAbstraction.hpp b/alib2common/src/abstraction/NormalizeAbstraction.hpp
index a0aa378852..58caf4295f 100644
--- a/alib2common/src/abstraction/NormalizeAbstraction.hpp
+++ b/alib2common/src/abstraction/NormalizeAbstraction.hpp
@@ -26,7 +26,7 @@ public:
 		if ( this->cached ( ) )
 			return true;
 
-		this->m_data = std::unique_ptr < ReturnType > ( ( ReturnType * ) std::move ( this->m_param->getData ( ) ).normalize ( ) );
+		this->m_data = ReturnType ( * std::unique_ptr < ReturnType > ( static_cast < ReturnType * > ( std::move ( this->m_param->getValue ( ) ).normalize ( ) ) ) );
 
 		return true;
 	}
diff --git a/alib2common/src/abstraction/NullaryOperationAbstraction.hpp b/alib2common/src/abstraction/NullaryOperationAbstraction.hpp
index a7eebcf460..d0a4ec6fb8 100644
--- a/alib2common/src/abstraction/NullaryOperationAbstraction.hpp
+++ b/alib2common/src/abstraction/NullaryOperationAbstraction.hpp
@@ -8,18 +8,18 @@
 #ifndef _NULLARY_OPERATION_ABSTRACTION_HPP_
 #define _NULLARY_OPERATION_ABSTRACTION_HPP_
 
-#include <abstraction/ResultClassSelector.hpp>
+#include <abstraction/ValueOperationAbstraction.hpp>
 #include <exception/CommonException.h>
 
 namespace abstraction {
 
 template < class ReturnType >
-class NullaryOperationAbstraction : public ResultClassSelector < ReturnType >::OutputClass {
+class NullaryOperationAbstraction : public ValueOperationAbstraction < ReturnType > {
 	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > &, unsigned ) override {
 		return false;
 	}
 
-	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & ) override {
+	virtual bool detachInput ( unsigned ) override {
 		return true;
 	}
 
diff --git a/alib2common/src/abstraction/OperationAbstraction.hpp b/alib2common/src/abstraction/OperationAbstraction.hpp
index c3065761a8..5726da3b35 100644
--- a/alib2common/src/abstraction/OperationAbstraction.hpp
+++ b/alib2common/src/abstraction/OperationAbstraction.hpp
@@ -21,7 +21,7 @@ namespace abstraction {
 class OperationAbstraction : public std::enable_shared_from_this < OperationAbstraction > {
 public:
 	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) = 0;
-	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) = 0;
+	virtual bool detachInput ( unsigned index ) = 0;
 
 	virtual ~OperationAbstraction ( ) noexcept {
 	}
diff --git a/alib2common/src/abstraction/ResultClassSelector.hpp b/alib2common/src/abstraction/ResultClassSelector.hpp
deleted file mode 100644
index b7a2813252..0000000000
--- a/alib2common/src/abstraction/ResultClassSelector.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * ResultClassSelector.hpp
- *
- *  Created on: 11. 7. 2017
- *	  Author: Jan Travnicek
- */
-
-#ifndef _RESULT_CLASS_SELECTOR_H_
-#define _RESULT_CLASS_SELECTOR_H_
-
-#include <abstraction/VoidOperationAbstraction.hpp>
-#include <abstraction/ValueOperationAbstraction.hpp>
-#include <tuple>
-
-namespace abstraction {
-
-template < class ReturnType >
-struct ResultClassSelector {
-	typedef ValueOperationAbstraction < ReturnType > OutputClass;
-};
-
-template < >
-struct ResultClassSelector < void > {
-	typedef VoidOperationAbstraction OutputClass;
-};
-
-} /* namespace abstraction */
-
-#endif /* _RESULT_CLASS_SELECTOR_H_ */
diff --git a/alib2common/src/abstraction/UnaryOperationAbstraction.hpp b/alib2common/src/abstraction/UnaryOperationAbstraction.hpp
index 074e7b79eb..bce9dae138 100644
--- a/alib2common/src/abstraction/UnaryOperationAbstraction.hpp
+++ b/alib2common/src/abstraction/UnaryOperationAbstraction.hpp
@@ -8,23 +8,23 @@
 #ifndef _UNARY_OPERATION_ABSTRACTION_HPP_
 #define _UNARY_OPERATION_ABSTRACTION_HPP_
 
-#include <abstraction/ResultClassSelector.hpp>
+#include <abstraction/ValueOperationAbstraction.hpp>
 #include <tuple>
 #include <abstraction/Registry.h>
 
 namespace abstraction {
 
 template < class ReturnType, class ParamType >
-class UnaryOperationAbstraction : public ResultClassSelector < ReturnType >::OutputClass {
+class UnaryOperationAbstraction : public ValueOperationAbstraction < ReturnType > {
 protected:
-	std::shared_ptr < ValueOperationAbstraction < typename std::decay < ParamType >::type > > m_param;
+	std::shared_ptr < ValueProvider < ParamType > > m_param;
 
 private:
 	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) override {
 		if ( index != 0 )
 			throw exception::CommonException ( "Out of range index: " + ext::to_string ( index ) + " max: " + ext::to_string ( numberOfParams ( ) ) + "." );
 
-		std::shared_ptr < ValueOperationAbstraction < ParamType > > validData = std::dynamic_pointer_cast < ValueOperationAbstraction < ParamType > > ( input );
+		std::shared_ptr < ValueProvider < ParamType > > validData = std::dynamic_pointer_cast < ValueProvider < ParamType > > ( input );
 		if ( validData ) {
 			m_param = validData;
 			return true;
@@ -33,8 +33,8 @@ private:
 		}
 	}
 
-	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) override {
-		if ( m_param != input )
+	virtual bool detachInput ( unsigned index ) override {
+		if ( index != 0 )
 			return false;
 
 		m_param = nullptr;
diff --git a/alib2common/src/abstraction/ValueOperationAbstraction.hpp b/alib2common/src/abstraction/ValueOperationAbstraction.hpp
index d29837b162..89a9d0a113 100644
--- a/alib2common/src/abstraction/ValueOperationAbstraction.hpp
+++ b/alib2common/src/abstraction/ValueOperationAbstraction.hpp
@@ -12,38 +12,246 @@
 #include <tuple>
 #include <memory>
 #include <typeindex>
+#include <variant>
 #include <abstraction/Registry.h>
 
 namespace abstraction {
 
+template < class Type >
+class ValueProvider {
+	bool m_move;
+
+protected:
+	virtual Type & getData ( ) const = 0;
+
+public:
+	typedef Type return_type;
+
+	ValueProvider ( ) : m_move ( false ) {
+	}
+
+	void setMove ( bool move ) {
+		m_move = move;
+	}
+
+	Type getValue ( ) const {
+		if ( m_move )
+			return std::move ( getData ( ) );
+		else
+			return getData ( );
+	}
+
+	virtual bool eval ( ) = 0;
+
+	virtual bool isReady ( ) const = 0;
+};
+
+template < class Type >
+class ValueProvider < Type & > {
+protected:
+	virtual Type & getData ( ) const = 0;
+
+public:
+	typedef Type return_type;
+
+	Type & getValueReference ( ) const {
+		return getData ( );
+	}
+
+	Type & getValue ( ) const {
+		return getData ( );
+	}
+
+	virtual bool eval ( ) = 0;
+
+	virtual bool isReady ( ) const = 0;
+};
+
+template < class Type >
+class ValueProvider < const Type & > {
+protected:
+	virtual const Type & getConstData ( ) const = 0;
+
+public:
+	typedef Type return_type;
+
+	const Type & getConstValueReference ( ) const {
+		return getConstData ( );
+	}
+
+	const Type & getValue ( ) const{
+		return getConstData ( );
+	}
+
+	virtual bool eval ( ) = 0;
+
+	virtual bool isReady ( ) const = 0;
+};
+
 template < class ReturnType >
-class ValueOperationAbstraction : public OperationAbstraction {
+class ValueOperationAbstraction : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & > {
 protected:
-	std::unique_ptr < ReturnType > m_data;
+	virtual ReturnType & getData ( ) const override {
+		return m_data.template get < ReturnType > ( );
+	}
+
+	virtual const ReturnType & getConstData ( ) const override {
+		return m_data.template get < ReturnType > ( );
+	}
+
+	mutable ext::variant < void, ReturnType > m_data;
 
 public:
-	typedef ReturnType return_type;
+	template < typename Callable, typename ... Ts, size_t ... Indexes >
+	inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) {
+		if ( ! isReady ( ) )
+			m_data = callback ( std::get < Indexes > ( inputs )->getValue ( ) ... );
+	}
+
+	template < typename Callable, typename T >
+	inline void run_helper ( Callable callback, const T & input ) const {
+		if ( ! isReady ( ) )
+			m_data = callback ( input->getValue ( ) );
+	}
+
+	virtual bool isReady ( ) const override {
+		return m_data.template is < ReturnType > ( );
+	}
+
+	virtual ext::type_index getReturnTypeIndex ( ) const override {
+		return ext::type_index ( typeid ( ReturnType ) );
+	}
+
+	virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
+		if ( isReady ( ) )
+			return ext::type_index ( typeid ( getData ( ) ) );
+		else
+			throw exception::CommonException ( "Runtime type unknown before evaluation." );
+	}
+
+	virtual bool cached ( ) const override {
+		return isReady ( );
+	}
+};
+
+template < class ReturnType >
+class ValueOperationAbstraction < ReturnType & > : public OperationAbstraction, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & > {
+protected:
+	virtual ReturnType & getData ( ) const override {
+		return m_data.template get < std::reference_wrapper < ReturnType > > ( ).get ( );
+	}
 
+	virtual const ReturnType & getConstData ( ) const override {
+		return m_data.template get < std::reference_wrapper < ReturnType > > ( ).get ( );
+	}
+
+	mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
+
+public:
 	template < typename Callable, typename ... Ts, size_t ... Indexes >
 	inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) {
-		if ( m_data == nullptr )
-			m_data = std::unique_ptr < ReturnType > ( callback ( std::get < Indexes > ( inputs )->getData ( ) ... ) );
+		if ( ! isReady ( ) )
+			m_data = std::reference_wrapper < ReturnType > ( callback ( std::get < Indexes > ( inputs )->getValue ( ) ... ) );
 	}
 
 	template < typename Callable, typename T >
 	inline void run_helper ( Callable callback, const T & input ) const {
-		if ( m_data == nullptr )
-			m_data = std::unique_ptr < ReturnType > ( callback ( input->getData ( ) ) );
+		if ( ! isReady ( ) )
+			m_data = std::reference_wrapper < ReturnType > ( callback ( input->getValue ( ) ) );
 	}
 
-	bool isReady ( ) const {
-		return m_data != nullptr;
+	virtual bool isReady ( ) const override {
+		return m_data.template is < std::reference_wrapper < ReturnType > > ( );
+	}
+
+	virtual ext::type_index getReturnTypeIndex ( ) const override {
+		return ext::type_index ( typeid ( ReturnType ) );
+	}
+
+	virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
+		if ( isReady ( ) )
+			return ext::type_index ( typeid ( getData ( ) ) );
+		else
+			throw exception::CommonException ( "Runtime type unknown before evaluation." );
+	}
+
+	virtual bool cached ( ) const override {
+		return isReady ( );
+	}
+};
+
+template < class ReturnType >
+class ValueOperationAbstraction < const ReturnType & > : public OperationAbstraction, public ValueProvider < const ReturnType & > {
+protected:
+	virtual const ReturnType & getConstData ( ) const override {
+		return m_data.template get < std::reference_wrapper < const ReturnType > > ( ).get ( );
+	}
+
+	mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
+
+public:
+	template < typename Callable, typename ... Ts, size_t ... Indexes >
+	inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) {
+		if ( ! isReady ( ) )
+			m_data = std::reference_wrapper < const ReturnType > ( callback ( std::get < Indexes > ( inputs )->getValue ( ) ... ) );
 	}
 
-	ReturnType & getData ( ) const {
+	template < typename Callable, typename T >
+	inline void run_helper ( Callable callback, const T & input ) const {
+		if ( ! isReady ( ) )
+			m_data = std::reference_wrapper < const ReturnType > ( callback ( input->getValue ( ) ) );
+	}
+
+	virtual bool isReady ( ) const override {
+		return m_data.template is < std::reference_wrapper < const ReturnType > > ( );
+	}
+
+	virtual ext::type_index getReturnTypeIndex ( ) const override {
+		return ext::type_index ( typeid ( ReturnType ) );
+	}
+
+	virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
+		if ( isReady ( ) )
+			return ext::type_index ( typeid ( getConstData ( ) ) );
+		else
+			throw exception::CommonException ( "Runtime type unknown before evaluation." );
+	}
+
+	virtual bool cached ( ) const override {
+		return isReady ( );
+	}
+};
+
+template < class ReturnType >
+class ValueOperationAbstraction < ReturnType * > : public OperationAbstraction, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & > {
+protected:
+	virtual ReturnType & getData ( ) const override {
+		return * m_data;
+	}
+
+	virtual const ReturnType & getConstData ( ) const override {
 		return * m_data;
 	}
 
+	std::unique_ptr < ReturnType > m_data;
+
+public:
+	template < typename Callable, typename ... Ts, size_t ... Indexes >
+	inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) {
+		if ( ! isReady ( ) )
+			m_data = std::unique_ptr < ReturnType > ( callback ( std::get < Indexes > ( inputs )->getValue ( ) ... ) );
+	}
+
+	template < typename Callable, typename T >
+	inline void run_helper ( Callable callback, const T & input ) const {
+		if ( ! isReady ( ) )
+			m_data = std::unique_ptr < ReturnType > ( callback ( input->getValue ( ) ) );
+	}
+
+	virtual bool isReady ( ) const override {
+		return m_data != nullptr;
+	}
+
 	virtual ext::type_index getReturnTypeIndex ( ) const override {
 		return ext::type_index ( typeid ( ReturnType ) );
 	}
@@ -60,6 +268,36 @@ public:
 	}
 };
 
+template < >
+class ValueOperationAbstraction < void > : public OperationAbstraction {
+public:
+	template < typename Callable, typename ... Ts, size_t ... Indexes >
+	inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) const {
+		callback ( std::get < Indexes > ( inputs )->getValue ( ) ... );
+	}
+
+	template < typename Callable, typename T >
+	inline void run_helper ( Callable callback, const T & input ) const {
+		callback ( input->getValue ( ) );
+	}
+
+	virtual bool isReady ( ) const {
+		return true;
+	}
+
+	virtual ext::type_index getReturnTypeIndex ( ) const override {
+		return ext::type_index ( typeid ( void ) );
+	}
+
+	virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
+		return ext::type_index ( typeid ( void ) );
+	}
+
+	virtual bool cached ( ) const override {
+		return false;
+	}
+};
+
 } /* namespace abstraction */
 
 #endif /* _VALUE_OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/ValuePrinterAbstraction.hpp b/alib2common/src/abstraction/ValuePrinterAbstraction.hpp
index 0c34388422..71318a04e8 100644
--- a/alib2common/src/abstraction/ValuePrinterAbstraction.hpp
+++ b/alib2common/src/abstraction/ValuePrinterAbstraction.hpp
@@ -23,7 +23,7 @@ public:
 		if ( ! this->inputsReady ( ) )
 			return false;
 
-		std::cout << this->m_param->getData ( ) << std::endl;
+		std::cout << this->m_param->getConstValueReference ( ) << std::endl;
 		return true;
 	}
 };
diff --git a/alib2common/src/abstraction/ValuePrinterRegistry.hpp b/alib2common/src/abstraction/ValuePrinterRegistry.hpp
index 92619c468e..f1ef0ae91e 100644
--- a/alib2common/src/abstraction/ValuePrinterRegistry.hpp
+++ b/alib2common/src/abstraction/ValuePrinterRegistry.hpp
@@ -66,7 +66,7 @@ namespace abstraction {
 
 template < class Param >
 std::shared_ptr < abstraction::OperationAbstraction > ValuePrinterRegistry::EntryImpl < Param >::getAbstraction ( ) const {
-	return std::make_shared < abstraction::ValuePrinterAbstraction < Param > > ( );
+	return std::make_shared < abstraction::ValuePrinterAbstraction < const Param & > > ( );
 }
 
 } /* namespace abstraction */
diff --git a/alib2common/src/abstraction/VoidOperationAbstraction.hpp b/alib2common/src/abstraction/VoidOperationAbstraction.hpp
deleted file mode 100644
index 28c2ff4736..0000000000
--- a/alib2common/src/abstraction/VoidOperationAbstraction.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * VoidOperationAbstraction.hpp
- *
- *  Created on: 11. 7. 2017
- *	  Author: Jan Travnicek
- */
-
-#ifndef _VOID_OPERATION_ABSTRACTION_HPP_
-#define _VOID_OPERATION_ABSTRACTION_HPP_
-
-#include <abstraction/OperationAbstraction.hpp>
-#include <tuple>
-
-namespace abstraction {
-
-class VoidOperationAbstraction : public OperationAbstraction {
-public:
-	template < typename Callable, typename ... Ts, size_t ... Indexes >
-	inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) const {
-		callback ( std::get < Indexes > ( inputs )->getData ( ) ... );
-	}
-
-	template < typename Callable, typename T >
-	inline void run_helper ( Callable callback, const T & input ) const {
-		callback ( input->getData ( ) );
-	}
-
-	virtual ext::type_index getReturnTypeIndex ( ) const override {
-		return ext::type_index ( typeid ( void ) );
-	}
-
-	virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
-		return ext::type_index ( typeid ( void ) );
-	}
-
-	virtual bool cached ( ) const override {
-		return false;
-	}
-};
-
-} /* namespace abstraction */
-
-#endif /* _VOID_OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp b/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp
index 9fb60ef3ec..8076918e34 100644
--- a/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp
+++ b/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp
@@ -25,7 +25,7 @@ public:
 		if ( ! this->inputsReady ( ) )
 			return false;
 
-		alib::XmlDataFactory::toFile ( this->m_param->getData ( ), m_filename );
+		alib::XmlDataFactory::toFile ( this->m_param->getConstValueReference ( ), m_filename );
 		return true;
 	}
 };
diff --git a/alib2common/src/abstraction/XmlFileWriterRegistry.hpp b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp
index 963639dbec..937360501c 100644
--- a/alib2common/src/abstraction/XmlFileWriterRegistry.hpp
+++ b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp
@@ -79,7 +79,7 @@ namespace abstraction {
 
 template < class Param >
 std::shared_ptr < abstraction::OperationAbstraction > XmlFileWriterRegistry::EntryImpl < Param >::getAbstraction ( std::string filename ) const {
-	return std::make_shared < abstraction::XmlFileWriterAbstraction < Param > > ( std::move ( filename ) );
+	return std::make_shared < abstraction::XmlFileWriterAbstraction < const Param & > > ( std::move ( filename ) );
 }
 
 
diff --git a/alib2common/src/abstraction/XmlParserAbstraction.hpp b/alib2common/src/abstraction/XmlParserAbstraction.hpp
index d3ada4ca18..5011921ef8 100644
--- a/alib2common/src/abstraction/XmlParserAbstraction.hpp
+++ b/alib2common/src/abstraction/XmlParserAbstraction.hpp
@@ -22,11 +22,11 @@ public:
 	}
 
 	virtual bool run ( ) override {
-		if ( this->m_data != nullptr )
+		if ( this->isReady ( ) )
 			return true;
 
 		ReturnType res = alib::XmlDataFactory::fromTokens ( std::move ( m_tokens ) );
-		this->m_data = std::unique_ptr < ReturnType > ( static_cast < ReturnType * > ( std::move ( res ).plunder ( ) ) );
+		this->m_data = std::move ( res );
 		return true;
 	}
 };
-- 
GitLab