From 74727d206e0ba646458ad6a34c964a8b491bf139 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 24 Sep 2017 09:14:56 +0200
Subject: [PATCH] detect normalize and downcast in abstraction

---
 alib2cli/test-src/cli/CliTest.cpp             | 36 ++++++++---------
 .../src/abstraction/AlgorithmRegistry.cpp     | 11 +-----
 .../src/abstraction/AlgorithmRegistry.hpp     | 22 ++---------
 alib2common/src/abstraction/CastRegistry.cpp  |  8 +---
 alib2common/src/abstraction/CastRegistry.hpp  | 39 +++++++------------
 .../src/abstraction/DowncastRegistry.cpp      |  5 +++
 .../src/abstraction/DowncastRegistry.hpp      |  2 +
 .../src/abstraction/NormalizeRegistry.cpp     |  5 +++
 .../src/abstraction/NormalizeRegistry.hpp     |  2 +
 .../src/abstraction/PrimitiveRegistrator.cpp  | 24 ++++++------
 alib2common/src/abstraction/Registry.cpp      | 16 +++++---
 alib2common/src/abstraction/Registry.h        |  5 ++-
 .../abstraction/common/AlgorithmHelper.cpp    |  9 ++---
 .../src/abstraction/common/CastHelper.cpp     |  6 +--
 .../src/registration/AlgoRegistration.hpp     | 13 +------
 .../src/registration/CastRegistration.hpp     |  8 ++--
 16 files changed, 86 insertions(+), 125 deletions(-)

diff --git a/alib2cli/test-src/cli/CliTest.cpp b/alib2cli/test-src/cli/CliTest.cpp
index dad46d5e42..bffcc57150 100644
--- a/alib2cli/test-src/cli/CliTest.cpp
+++ b/alib2cli/test-src/cli/CliTest.cpp
@@ -73,13 +73,13 @@ public:
 };
 
 void CliTest::testCreateUnique ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < One > ( One::one, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Two > ( Two::two, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Add > ( Add::add, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 2 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Add > ( Add::add2, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 2 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Neg > ( Neg::neg, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Divide > ( Divide::divide, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 2 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Divide > ( Divide::divide2, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 2 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < One > ( One::one, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Two > ( Two::two, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Add > ( Add::add, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 2 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Add > ( Add::add2, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 2 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Neg > ( Neg::neg, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Divide > ( Divide::divide, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 2 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Divide > ( Divide::divide2, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 2 > ( ) );
 
 	mkdir ( "local", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
 
@@ -122,8 +122,8 @@ public:
 };
 
 void CliTest::testMove ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < Source > ( Source::source, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < Sink > ( Sink::sink, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Source > ( Source::source, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Sink > ( Sink::sink, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 	cli::Environment environment;
 	cli::Parser parser ( cli::Lexer ( "execute Source | Sink ^ - >" ) );
@@ -148,8 +148,8 @@ public:
 };
 
 void CliTest::testRvalueReferencePassing ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < RvalueReferenceProvider > ( RvalueReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < RvalueReferenceAcceptor > ( RvalueReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < RvalueReferenceProvider > ( RvalueReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < RvalueReferenceAcceptor > ( RvalueReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 	try {
 		source = std::make_unique < int > ( 1 );
@@ -187,8 +187,8 @@ public:
 };
 
 void CliTest::testConstReferencePassing ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < ConstReferenceProvider > ( ConstReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < ConstReferenceAcceptor > ( ConstReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < ConstReferenceProvider > ( ConstReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < ConstReferenceAcceptor > ( ConstReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 	cli::Environment environment;
 	cli::Parser parser ( cli::Lexer ( "execute ConstReferenceProvider | ConstReferenceAcceptor - >" ) );
@@ -210,8 +210,8 @@ public:
 };
 
 void CliTest::testReferencePassing ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < ReferenceProvider > ( ReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < ReferenceAcceptor > ( ReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < ReferenceProvider > ( ReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < ReferenceAcceptor > ( ReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 	cli::Environment environment;
 	cli::Parser parser ( cli::Lexer ( "execute ReferenceProvider | ReferenceAcceptor - >" ) );
@@ -234,8 +234,8 @@ public:
 };
 
 void CliTest::testConstRvalueReferencePassing ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < ConstRvalueReferenceProvider > ( ConstRvalueReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 0 > ( ) );
-	abstraction::AlgorithmRegistry::registerAlgorithm < ConstRvalueReferenceAcceptor > ( ConstRvalueReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < ConstRvalueReferenceProvider > ( ConstRvalueReferenceProvider::foo, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 0 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < ConstRvalueReferenceAcceptor > ( ConstRvalueReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 	cli::Environment environment;
 	cli::Parser parser ( cli::Lexer ( "execute ConstRvalueReferenceProvider | ConstRvalueReferenceAcceptor ^ - >" ) );
@@ -252,7 +252,7 @@ public:
 };
 
 void CliTest::testSetConstruction ( ) {
-	abstraction::AlgorithmRegistry::registerAlgorithm < Print > ( Print::print, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, false, false, std::array < std::string, 1 > ( ) );
+	abstraction::AlgorithmRegistry::registerAlgorithm < Print > ( Print::print, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 	cli::Environment environment;
 	cli::Parser parser ( cli::Lexer ( "execute { :int 1 2 3 } > $set" ) );
diff --git a/alib2common/src/abstraction/AlgorithmRegistry.cpp b/alib2common/src/abstraction/AlgorithmRegistry.cpp
index 133c255346..a0a4cdc678 100644
--- a/alib2common/src/abstraction/AlgorithmRegistry.cpp
+++ b/alib2common/src/abstraction/AlgorithmRegistry.cpp
@@ -11,7 +11,7 @@
 
 namespace abstraction {
 
-std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory, bool & downcast, bool & normalize ) {
+std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory ) {
 	auto group = getEntries ( ).find ( name );
 	if ( group == getEntries ( ).end ( ) ) {
 		ext::vector < std::string > explodedName = ext::explode ( name, "::" );
@@ -136,18 +136,9 @@ std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::getAbst
 		throw exception::CommonException ( "Entry overload " + ss.str ( ) + " not available." );
 	}
 
-	downcast = best->getDowncast ( );
-	normalize = best->getNormalize ( );
-
 	return best->getAbstraction ( );
 }
 
-std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory category ) {
-	bool downcast;
-	bool normalize;
-	return getAbstraction ( name, paramTypes, category, downcast, normalize );
-}
-
 ext::set < std::string > AlgorithmRegistry::listGroup ( const std::string & group ) {
 	ext::set < std::string > res;
 
diff --git a/alib2common/src/abstraction/AlgorithmRegistry.hpp b/alib2common/src/abstraction/AlgorithmRegistry.hpp
index d0f4b8eb53..4553f81b3d 100644
--- a/alib2common/src/abstraction/AlgorithmRegistry.hpp
+++ b/alib2common/src/abstraction/AlgorithmRegistry.hpp
@@ -27,22 +27,8 @@ namespace abstraction {
 
 class AlgorithmRegistry {
 	class Entry {
-		bool m_downcast;
-		bool m_normalize;
-
 	public:
-		Entry ( bool downcast, bool normalize ) : m_downcast ( downcast ), m_normalize ( normalize ) {
-		}
-
 		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
-
-		bool getDowncast ( ) const {
-			return m_downcast;
-		}
-
-		bool getNormalize ( ) const {
-			return m_normalize;
-		}
 	};
 
 	template < class Return, class ... Params >
@@ -50,7 +36,7 @@ class AlgorithmRegistry {
 		std::function < Return ( Params ... ) > m_callback;
 
 	public:
-		EntryImpl ( std::function < Return ( Params ... ) > callback, bool downcast, bool normalize ) : Entry ( downcast, normalize ), m_callback ( callback ) {
+		EntryImpl ( std::function < Return ( Params ... ) > callback ) : m_callback ( callback ) {
 		}
 
 		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
@@ -68,7 +54,7 @@ class AlgorithmRegistry {
 	};
 public:
 	template < class Algo, class ReturnType, class ... ParamTypes >
-	static void registerAlgorithm ( ReturnType ( * callback ) ( ParamTypes ... ), AlgorithmCategories::AlgorithmCategory category, bool downcast, bool normalize, std::array < std::string, sizeof ... ( ParamTypes ) > paramNames ) {
+	static void registerAlgorithm ( ReturnType ( * callback ) ( ParamTypes ... ), AlgorithmCategories::AlgorithmCategory category, std::array < std::string, sizeof ... ( ParamTypes ) > paramNames ) {
 		/* make unused parameter warning go away in case of sizeof ... ( ParamTypes ) == 0 */
 		( void ) paramNames;
 
@@ -84,12 +70,10 @@ public:
 				throw exception::CommonException ( "Callback for " + algorithm + " already registered." );
 
 		ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > result = ext::make_pair ( ext::to_string < typename std::decay < ReturnType >::type > ( ), abstraction::ParamQualifiers::paramQualifiers < ReturnType > ( ) );
-		ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < Entry > > entryValue = ext::make_pair ( std::move ( result ), std::make_shared < EntryImpl < ReturnType, ParamTypes ... > > ( callback, downcast, normalize ) );
+		ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < Entry > > entryValue = ext::make_pair ( std::move ( result ), std::make_shared < EntryImpl < ReturnType, ParamTypes ... > > ( callback ) );
 		group.push_back ( ext::make_tuple ( category, params, entryValue ) );
 	}
 
-	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory category, bool & downcast, bool & normalize );
-
 	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory category );
 
 	static ext::set < std::string > listGroup ( const std::string & group );
diff --git a/alib2common/src/abstraction/CastRegistry.cpp b/alib2common/src/abstraction/CastRegistry.cpp
index aa97741cae..d6f101aa33 100644
--- a/alib2common/src/abstraction/CastRegistry.cpp
+++ b/alib2common/src/abstraction/CastRegistry.cpp
@@ -13,7 +13,7 @@
 
 namespace abstraction {
 
-std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::getAbstraction ( const std::string & target, const std::string & param, bool & normalize ) {
+std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::getAbstraction ( const std::string & target, const std::string & param ) {
 	std::set < std::string > targetTypes;
 	if ( alib::namingApi::hasTypes ( target ) )
 		targetTypes = ext::transform < std::string > ( alib::namingApi::getTypes ( target ), [ ] ( const ext::type_index & type ) { return ext::to_string ( type ); } );
@@ -23,7 +23,6 @@ std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::getAbstracti
 	for ( const std::string & toType : targetTypes ) {
 		auto cast = getEntries ( ).find ( std::make_pair ( toType, param ) );
 		if ( cast != getEntries ( ).end ( ) ) {
-			normalize = cast->second->getNormalize ( );
 			return cast->second->getAbstraction ( );
 		}
 	}
@@ -61,11 +60,6 @@ bool CastRegistry::castAvailable ( const std::string & target, const std::string
 	return false;
 }
 
-std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::getAbstraction ( const std::string & target, const std::string & param ) {
-	bool normalize;
-	return getAbstraction ( target, param, normalize );
-}
-
 ext::set < std::string > CastRegistry::listFrom ( const std::string & type ) {
 	std::set < std::string > sourceTypes;
 
diff --git a/alib2common/src/abstraction/CastRegistry.hpp b/alib2common/src/abstraction/CastRegistry.hpp
index e53379211b..914a846dba 100644
--- a/alib2common/src/abstraction/CastRegistry.hpp
+++ b/alib2common/src/abstraction/CastRegistry.hpp
@@ -20,25 +20,14 @@ namespace abstraction {
 
 class CastRegistry {
 	class Entry {
-		bool m_normalize;
 	public:
-		Entry ( bool normalize ) : m_normalize ( normalize ) {
-		}
-
 		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
 
-		bool getNormalize ( ) const {
-			return m_normalize;
-		}
-
 	};
 
 	template < class Return, class Param >
 	class DefaultEntryImpl : public Entry {
 	public:
-		DefaultEntryImpl ( bool normalize ) : Entry ( normalize ) {
-		}
-
 		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
 	};
 
@@ -46,7 +35,7 @@ class CastRegistry {
 	class AlgorithmEntryImpl : public Entry {
 		std::function < Return ( Param ) > m_callback;
 	public:
-		AlgorithmEntryImpl ( std::function < Return ( Param ) > callback, bool normalize ) : Entry ( normalize ), m_callback ( callback ) {
+		AlgorithmEntryImpl ( std::function < Return ( Param ) > callback ) : m_callback ( callback ) {
 		}
 
 		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
@@ -59,49 +48,47 @@ class CastRegistry {
 
 public:
 	template < class TargetType, class ParamType >
-	static void registerCast ( std::string target, std::string param, bool normalize ) {
-		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new DefaultEntryImpl < TargetType, ParamType > ( normalize ) ) ) ).second )
+	static void registerCast ( std::string target, std::string param ) {
+		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new DefaultEntryImpl < TargetType, ParamType > ( ) ) ) ).second )
 			throw exception::CommonException ( "Entry from " + param + " to " + target + " already registered." );
 	}
 
 	template < class TargetType, class ParamType >
-	static void registerCast ( bool normalize ) {
+	static void registerCast ( ) {
 		std::string target = ext::to_string < TargetType > ( );
 		std::string param = ext::to_string < ParamType > ( );
 
-		registerCast < TargetType, ParamType > ( target, param, normalize );
+		registerCast < TargetType, ParamType > ( target, param );
 	}
 
 	template < class TargetType, class ParamType >
-	static void registerCastAlgorithm ( std::string target, std::string param, TargetType ( * callback ) ( const ParamType & ), bool normalize ) {
-		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new AlgorithmEntryImpl < TargetType, const ParamType & > ( callback, normalize ) ) ) ).second )
+	static void registerCastAlgorithm ( std::string target, std::string param, TargetType ( * callback ) ( const ParamType & ) ) {
+		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new AlgorithmEntryImpl < TargetType, const ParamType & > ( callback ) ) ) ).second )
 			throw exception::CommonException ( "Entry from " + param + " to " + target + " already registered." );
 	}
 
 	template < class TargetType, class ParamType >
-	static void registerCastAlgorithm ( TargetType ( * callback ) ( const ParamType & ), bool normalize ) {
+	static void registerCastAlgorithm ( TargetType ( * callback ) ( const ParamType & ) ) {
 		std::string target = ext::to_string < TargetType > ( );
 		std::string param = ext::to_string < ParamType > ( );
 
-		registerCastAlgorithm < TargetType, ParamType > ( target, param, callback, normalize );
+		registerCastAlgorithm < TargetType, ParamType > ( target, param, callback );
 	}
 
 	template < class TargetType, class ParamType >
-	static void registerCastAlgorithm ( std::string target, std::string param, TargetType ( * callback ) ( ParamType ), bool normalize ) {
-		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new AlgorithmEntryImpl < TargetType, ParamType > ( callback, normalize ) ) ) ).second )
+	static void registerCastAlgorithm ( std::string target, std::string param, TargetType ( * callback ) ( ParamType ) ) {
+		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new AlgorithmEntryImpl < TargetType, ParamType > ( callback ) ) ) ).second )
 			throw exception::CommonException ( "Entry from " + param + " to " + target + " already registered." );
 	}
 
 	template < class TargetType, class ParamType >
-	static void registerCastAlgorithm ( TargetType ( * callback ) ( ParamType ), bool normalize ) {
+	static void registerCastAlgorithm ( TargetType ( * callback ) ( ParamType ) ) {
 		std::string target = ext::to_string < TargetType > ( );
 		std::string param = ext::to_string < ParamType > ( );
 
-		registerCastAlgorithm < TargetType, ParamType > ( target, param, callback, normalize );
+		registerCastAlgorithm < TargetType, ParamType > ( target, param, callback );
 	}
 
-	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & target, const std::string & param, bool & normalize );
-
 	static bool isNoOp ( const std::string & target, const std::string & param );
 
 	static bool castAvailable ( const std::string & target, const std::string & param );
diff --git a/alib2common/src/abstraction/DowncastRegistry.cpp b/alib2common/src/abstraction/DowncastRegistry.cpp
index 6d1be65041..5ec1554f77 100644
--- a/alib2common/src/abstraction/DowncastRegistry.cpp
+++ b/alib2common/src/abstraction/DowncastRegistry.cpp
@@ -17,4 +17,9 @@ std::shared_ptr < abstraction::OperationAbstraction > DowncastRegistry::getAbstr
 	return res->second->getAbstraction ( );
 }
 
+bool DowncastRegistry::hasDowncast ( const std::string & concrete, const std::string & base ) {
+	auto res = getEntries ( ).find ( std::make_pair ( concrete, base ) );
+	return res != getEntries ( ).end ( );
+}
+
 } /* namespace abstraction */
diff --git a/alib2common/src/abstraction/DowncastRegistry.hpp b/alib2common/src/abstraction/DowncastRegistry.hpp
index d70ab37a79..17579a6dfb 100644
--- a/alib2common/src/abstraction/DowncastRegistry.hpp
+++ b/alib2common/src/abstraction/DowncastRegistry.hpp
@@ -47,6 +47,8 @@ public:
 			throw exception::CommonException ( "Downcasting for " + base + " to " + concrete + " already registered." );
 	}
 
+	static bool hasDowncast ( const std::string & concrete, const std::string & base );
+
 	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & concrete, const std::string & base );
 };
 
diff --git a/alib2common/src/abstraction/NormalizeRegistry.cpp b/alib2common/src/abstraction/NormalizeRegistry.cpp
index 0c47a9153e..9eeb363a90 100644
--- a/alib2common/src/abstraction/NormalizeRegistry.cpp
+++ b/alib2common/src/abstraction/NormalizeRegistry.cpp
@@ -17,4 +17,9 @@ std::shared_ptr < abstraction::OperationAbstraction > NormalizeRegistry::getAbst
 	return res->second->getAbstraction ( );
 }
 
+bool NormalizeRegistry::hasNormalize ( const std::string & param ) {
+	auto res = getEntries ( ).find ( param );
+	return res != getEntries ( ).end ( );
+}
+
 } /* namespace abstraction */
diff --git a/alib2common/src/abstraction/NormalizeRegistry.hpp b/alib2common/src/abstraction/NormalizeRegistry.hpp
index fc5e768ff8..8e3ff68ed5 100644
--- a/alib2common/src/abstraction/NormalizeRegistry.hpp
+++ b/alib2common/src/abstraction/NormalizeRegistry.hpp
@@ -50,6 +50,8 @@ public:
 		registerNormalize < ParamType > ( std::move ( param ) );
 	}
 
+	static bool hasNormalize ( const std::string & param );
+
 	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & param );
 };
 
diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp
index 9e1c09738f..c055930066 100644
--- a/alib2common/src/abstraction/PrimitiveRegistrator.cpp
+++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp
@@ -23,22 +23,22 @@ namespace {
 class PrimitiveRegistrator {
 public:
 	PrimitiveRegistrator ( ) {
-		abstraction::CastRegistry::registerCast < double, int > ( false );
-		abstraction::CastRegistry::registerCast < int, double > ( false );
+		abstraction::CastRegistry::registerCast < double, int > ( );
+		abstraction::CastRegistry::registerCast < int, double > ( );
 
-		abstraction::CastRegistry::registerCastAlgorithm < std::string, int > ( ext::to_string, false );
-		abstraction::CastRegistry::registerCastAlgorithm < int, std::string > ( ( int ( * ) ( std::string ) ) ext::from_string < int >, false );
+		abstraction::CastRegistry::registerCastAlgorithm < std::string, int > ( ext::to_string );
+		abstraction::CastRegistry::registerCastAlgorithm < int, std::string > ( ( int ( * ) ( std::string ) ) ext::from_string < int > );
 
-		abstraction::CastRegistry::registerCast < bool, int > ( false );
-		abstraction::CastRegistry::registerCastAlgorithm < bool, std::string > ( ( bool ( * ) ( std::string ) ) ext::from_string < bool >, false );
-		abstraction::CastRegistry::registerCastAlgorithm < unsigned, std::string > ( "unsigned", ext::to_string < std::string > ( ), ( unsigned ( * ) ( std::string ) ) ext::from_string < unsigned >, false );
-		abstraction::CastRegistry::registerCastAlgorithm < double, std::string > ( ( double ( * ) ( std::string ) ) ext::from_string < double >, false );
+		abstraction::CastRegistry::registerCast < bool, int > ( );
+		abstraction::CastRegistry::registerCastAlgorithm < bool, std::string > ( ( bool ( * ) ( std::string ) ) ext::from_string < bool > );
+		abstraction::CastRegistry::registerCastAlgorithm < unsigned, std::string > ( "unsigned", ext::to_string < std::string > ( ), ( unsigned ( * ) ( std::string ) ) ext::from_string < unsigned > );
+		abstraction::CastRegistry::registerCastAlgorithm < double, std::string > ( ( double ( * ) ( std::string ) ) ext::from_string < double > );
 
-		abstraction::CastRegistry::registerCast < size_t, int > ( "size_t", ext::to_string < int > ( ), false );
-		abstraction::CastRegistry::registerCast < size_t, int > ( false );
-		abstraction::CastRegistry::registerCast < int, size_t > ( false );
+		abstraction::CastRegistry::registerCast < size_t, int > ( "size_t", ext::to_string < int > ( ) );
+		abstraction::CastRegistry::registerCast < size_t, int > ( );
+		abstraction::CastRegistry::registerCast < int, size_t > ( );
 
-		abstraction::CastRegistry::registerCast < int, primitive::Integer > ( false );
+		abstraction::CastRegistry::registerCast < int, primitive::Integer > ( );
 
 		abstraction::ContainerRegistry::registerSet < int > ( );
 
diff --git a/alib2common/src/abstraction/Registry.cpp b/alib2common/src/abstraction/Registry.cpp
index 48b58db362..3d658d70a6 100644
--- a/alib2common/src/abstraction/Registry.cpp
+++ b/alib2common/src/abstraction/Registry.cpp
@@ -55,12 +55,8 @@ std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbst
 	return AlgorithmRegistry::getAbstraction ( name, paramTypes, category );
 }
 
-std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory category, bool & unwrap, bool & normalize ) {
-	return AlgorithmRegistry::getAbstraction ( name, paramTypes, category, unwrap, normalize );
-}
-
-std::shared_ptr < abstraction::OperationAbstraction > Registry::getCastAbstraction ( const std::string & target, const std::string & param, bool & normalize ) {
-	return CastRegistry::getAbstraction ( target, param, normalize );
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getCastAbstraction ( const std::string & target, const std::string & param ) {
+	return CastRegistry::getAbstraction ( target, param );
 }
 
 bool Registry::isCastNoOp ( const std::string & target, const std::string & param ) {
@@ -75,10 +71,18 @@ std::shared_ptr < abstraction::OperationAbstraction > Registry::getNormalizeAbst
 	return NormalizeRegistry::getAbstraction ( param );
 }
 
+bool Registry::hasNormalize ( const std::string & param ) {
+	return NormalizeRegistry::hasNormalize ( param );
+}
+
 std::shared_ptr < abstraction::OperationAbstraction > Registry::getDowncastAbstraction ( const std::string & concrete, const std::string & base ) {
 	return DowncastRegistry::getAbstraction ( concrete, base );
 }
 
+bool Registry::hasDowncast ( const std::string & concrete, const std::string & base ) {
+	return DowncastRegistry::hasDowncast ( concrete, base );
+}
+
 std::shared_ptr < abstraction::OperationAbstraction > Registry::getValuePrinterAbstraction ( const std::string & param, std::ostream & os ) {
 	return ValuePrinterRegistry::getAbstraction ( param, os );
 }
diff --git a/alib2common/src/abstraction/Registry.h b/alib2common/src/abstraction/Registry.h
index ae3fc81cae..532b55c206 100644
--- a/alib2common/src/abstraction/Registry.h
+++ b/alib2common/src/abstraction/Registry.h
@@ -32,12 +32,13 @@ public:
 
 	static std::shared_ptr < abstraction::OperationAbstraction > getContainerAbstraction ( const std::string & container, const std::string & type );
 	static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory );
-	static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory, bool & unwrap, bool & normalize );
-	static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( const std::string & target, const std::string & param, bool & normalize );
+	static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( const std::string & target, const std::string & param );
 	static bool isCastNoOp ( const std::string & target, const std::string & param );
 	static std::shared_ptr < abstraction::OperationAbstraction > getImmediateAbstraction ( const std::string & result, std::string value );
 	static std::shared_ptr < abstraction::OperationAbstraction > getNormalizeAbstraction ( const std::string & param );
+	static bool hasNormalize ( const std::string & param );
 	static std::shared_ptr < abstraction::OperationAbstraction > getDowncastAbstraction ( const std::string & concrete, const std::string & base );
+	static bool hasDowncast ( const std::string & concrete, const std::string & base );
 	static std::shared_ptr < abstraction::OperationAbstraction > getValuePrinterAbstraction ( const std::string & param, std::ostream & os );
 };
 
diff --git a/alib2common/src/abstraction/common/AlgorithmHelper.cpp b/alib2common/src/abstraction/common/AlgorithmHelper.cpp
index 29e7670f93..9a34983982 100644
--- a/alib2common/src/abstraction/common/AlgorithmHelper.cpp
+++ b/alib2common/src/abstraction/common/AlgorithmHelper.cpp
@@ -17,10 +17,7 @@ std::shared_ptr < abstraction::OperationAbstraction > AlgorithmHelper::eval ( co
 	for ( const std::shared_ptr < abstraction::OperationAbstraction > & param : params )
 		paramTypes.push_back ( param->getReturnType ( ) );
 
-	bool downcast = false;
-	bool normalize = false;
-
-	std::shared_ptr < abstraction::OperationAbstraction > algo = abstraction::Registry::getAlgorithmAbstraction ( name, paramTypes, category, downcast, normalize );
+	std::shared_ptr < abstraction::OperationAbstraction > algo = abstraction::Registry::getAlgorithmAbstraction ( name, paramTypes, category );
 
 	unsigned i = 0;
 	ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > casted_params;
@@ -44,7 +41,7 @@ std::shared_ptr < abstraction::OperationAbstraction > AlgorithmHelper::eval ( co
 	if ( ! algo->eval ( ) )
 		throw exception::CommonException ( "Eval of algorithm " + name + " failed." );
 
-	if ( downcast ) {
+	if ( abstraction::Registry::hasDowncast ( algo->getRuntimeReturnType ( ), algo->getReturnType ( ) ) ) {
 		std::shared_ptr < abstraction::OperationAbstraction > downcaster = abstraction::Registry::getDowncastAbstraction ( algo->getRuntimeReturnType ( ), algo->getReturnType ( ) );
 		if ( ! downcaster->attachInput ( algo, 0, true ) )
 			throw exception::CommonException ( "Can't connect param at 0 of downcast of algorithm " + name + " with result of type " + algo->getReturnType ( ) + "." );
@@ -54,7 +51,7 @@ std::shared_ptr < abstraction::OperationAbstraction > AlgorithmHelper::eval ( co
 		algo = downcaster;
 	}
 
-	if ( normalize ) {
+	if ( abstraction::Registry::hasNormalize ( algo->getReturnType ( ) ) ) {
 		std::shared_ptr < abstraction::OperationAbstraction > normalized = abstraction::Registry::getNormalizeAbstraction ( algo->getReturnType ( ) );
 		if ( ! normalized->attachInput ( algo, 0, true ) )
 			throw exception::CommonException ( "Can't connect param at 0 of normalize of algorithm " + name + " with result of type " + algo->getReturnType ( ) + "." );
diff --git a/alib2common/src/abstraction/common/CastHelper.cpp b/alib2common/src/abstraction/common/CastHelper.cpp
index a613d7a20a..5592a67dc4 100644
--- a/alib2common/src/abstraction/common/CastHelper.cpp
+++ b/alib2common/src/abstraction/common/CastHelper.cpp
@@ -9,15 +9,13 @@ std::shared_ptr < abstraction::OperationAbstraction > CastHelper::eval ( const s
 		return param;
 	}
 
-	bool normalize;
-
-	std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getCastAbstraction ( type, param->getReturnType ( ), normalize );
+	std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getCastAbstraction ( type, param->getReturnType ( ) );
 	if ( ! res->attachInput ( param, 0, move ) )
 		throw exception::CommonException ( "Can't connect param at 0 of cast to " + type + " with result of type " + param->getReturnType ( ) + "." );
 	if ( ! res->eval ( ) )
 		throw exception::CommonException ( "Eval of cast to " + type + " failed." );
 
-	if ( normalize ) {
+	if ( abstraction::Registry::hasNormalize ( res->getReturnType ( ) ) ) {
 		std::shared_ptr < abstraction::OperationAbstraction > normalized = abstraction::Registry::getNormalizeAbstraction ( res->getReturnType ( ) );
 		if ( ! normalized->attachInput ( res, 0, true ) )
 			throw exception::CommonException ( "Can't connect param at 0 of normalize of cast to " + type + " with result of type " + res->getReturnType ( ) + "." );
diff --git a/alib2common/src/registration/AlgoRegistration.hpp b/alib2common/src/registration/AlgoRegistration.hpp
index e202d52437..87054f6771 100644
--- a/alib2common/src/registration/AlgoRegistration.hpp
+++ b/alib2common/src/registration/AlgoRegistration.hpp
@@ -17,28 +17,19 @@ public:
 	}
 };
 
-template < class Type, typename enable = void >
-struct RequireDowncast : std::false_type {
-};
-
-template < class Type >
-struct RequireDowncast < Type *, typename std::enable_if < ! std::is_final < Type >::value >::type > : public std::true_type {
-};
-
 template < class Algorithm, class ReturnType, class ... ParameterTypes >
 class AbstractRegister {
 public:
 	template < class ... ParamNames, typename std::enable_if < sizeof ... ( ParamNames ) <= sizeof ... ( ParameterTypes ) >::type * = nullptr >
 	AbstractRegister ( ReturnType ( * callback ) ( ParameterTypes ... ), abstraction::AlgorithmCategories::AlgorithmCategory category, ParamNames ... paramNames ) {
-		bool normalize = registration::NormalizationRegister < ReturnType > ( ).requireNormalization ( );
-		bool downcast = RequireDowncast < ReturnType >::value;
+		registration::NormalizationRegister < ReturnType > ( );
 
 		std::array < std::string, sizeof ... ( ParameterTypes ) > parameterNames = { { paramNames ... } };
 		for ( unsigned i = sizeof ... ( ParamNames ); i < sizeof ... ( ParameterTypes ); ++i ) {
 			parameterNames [ i ] = "arg" + ext::to_string ( i );
 		}
 
-		abstraction::AlgorithmRegistry::registerAlgorithm < Algorithm, ReturnType, ParameterTypes ... > ( callback, category, downcast, normalize, std::move ( parameterNames ) );
+		abstraction::AlgorithmRegistry::registerAlgorithm < Algorithm, ReturnType, ParameterTypes ... > ( callback, category, std::move ( parameterNames ) );
 	}
 
 	template < class ... ParamNames, typename std::enable_if < sizeof ... ( ParamNames ) <= sizeof ... ( ParameterTypes ) >::type * = nullptr >
diff --git a/alib2common/src/registration/CastRegistration.hpp b/alib2common/src/registration/CastRegistration.hpp
index 2297a86eaf..c89b2feb2e 100644
--- a/alib2common/src/registration/CastRegistration.hpp
+++ b/alib2common/src/registration/CastRegistration.hpp
@@ -14,15 +14,15 @@ public:
 	CastRegister ( ) {
 		alib::castApi::getCastPool < To > ( ).template add < From > ( );
 
-		bool normalize = registration::NormalizationRegister < To > ( ).requireNormalization ( );
-		abstraction::CastRegistry::registerCast < To, From > ( normalize );
+		registration::NormalizationRegister < To > ( );
+		abstraction::CastRegistry::registerCast < To, From > ( );
 	}
 
 	CastRegister ( To ( * castFunction ) ( const From & ) ) {
 		alib::castApi::getCastPool < To > ( ).template add < From > ( castFunction );
 
-		bool normalize = registration::NormalizationRegister < To > ( ).requireNormalization ( );
-		abstraction::CastRegistry::registerCastAlgorithm < To, From > ( castFunction, normalize );
+		registration::NormalizationRegister < To > ( );
+		abstraction::CastRegistry::registerCastAlgorithm < To, From > ( castFunction );
 	}
 };
 
-- 
GitLab