From 1c1b702df4dbb3f8c8f4de135984c2582c48f90f Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 29 Jan 2019 23:50:07 +0100
Subject: [PATCH] improvements in unregister functionality

---
 .../src/registry/AlgorithmRegistry.cpp        | 11 ++++--
 .../src/registry/AlgorithmRegistry.hpp        | 13 +++++++
 alib2common/src/core/components.hpp           | 38 +++++++++++++++++++
 .../src/core/components/setComponents.hpp     | 14 +++++++
 alib2xml/src/core/xmlApi.hpp                  | 10 +++++
 5 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/alib2abstraction/src/registry/AlgorithmRegistry.cpp b/alib2abstraction/src/registry/AlgorithmRegistry.cpp
index 605930c7fc..364236583e 100644
--- a/alib2abstraction/src/registry/AlgorithmRegistry.cpp
+++ b/alib2abstraction/src/registry/AlgorithmRegistry.cpp
@@ -35,7 +35,7 @@ void AlgorithmRegistry::registerInternal ( std::string algorithm, ext::vector <
 }
 
 void AlgorithmRegistry::unregisterInternal ( std::string algorithm, ext::vector < std::string > templateParams, AlgorithmCategories::AlgorithmCategory category, ext::vector < ext::tuple < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier >, std::string > > params ) {
-	auto & group = getEntries ( ) [ ext::make_pair ( std::move ( algorithm ), std::move ( templateParams ) ) ];
+	auto & group = getEntries ( ) [ ext::make_pair ( algorithm, templateParams ) ];
 	auto iter = find_if ( group.begin ( ), group.end ( ), [ & ] ( const ext::tuple < AlgorithmCategories::AlgorithmCategory, ext::vector < ext::tuple < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier >, std::string > >, ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < Entry > > > & entry ) {
 				if ( std::get < 0 > ( entry ) != category )
 					return false;
@@ -53,8 +53,13 @@ void AlgorithmRegistry::unregisterInternal ( std::string algorithm, ext::vector
 
 				return true;
 			} );
-	if ( iter != group.end ( ) )
-		group.erase ( iter );
+	if ( iter == group.end ( ) ) {
+		if ( templateParams.size ( ) == 0 )
+			throw std::invalid_argument ( "Entry " + algorithm + " with parameters " + ext::to_string ( params ) + " not registered." );
+		else
+			throw std::invalid_argument ( "Templated entry " + algorithm + " < " + ext::to_string ( templateParams ) + " > with parameters " + ext::to_string ( params ) + " not registered." );
+	}
+	group.erase ( iter );
 }
 
 ext::map < ext::pair < std::string, ext::vector < std::string > >, ext::list < ext::tuple < AlgorithmCategories::AlgorithmCategory, ext::vector < ext::tuple < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier >, std::string > >, ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < AlgorithmRegistry::Entry > > > > >::const_iterator AlgorithmRegistry::findAbstractionGroup ( const std::string & name, const ext::vector < std::string > & templateParams ) {
diff --git a/alib2abstraction/src/registry/AlgorithmRegistry.hpp b/alib2abstraction/src/registry/AlgorithmRegistry.hpp
index 18683a0de2..2d696ecd14 100644
--- a/alib2abstraction/src/registry/AlgorithmRegistry.hpp
+++ b/alib2abstraction/src/registry/AlgorithmRegistry.hpp
@@ -141,6 +141,19 @@ public:
 		unregisterInternal ( std::move ( algorithm ), std::move ( templateParams ), category, std::move ( params ) );
 	}
 
+	template < class Algo, class ... ParamTypes >
+	static void unregisterWrapper ( ) {
+		AlgorithmCategories::AlgorithmCategory category = AlgorithmCategories::AlgorithmCategory::DEFAULT;
+
+		std::string algorithm = ext::to_string < Algo > ( );
+		ext::vector < std::string > templateParams = ext::get_template_info ( algorithm );
+		algorithm = ext::erase_template_info ( algorithm );
+
+		ext::vector < ext::tuple < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier >, std::string > > params = convertParamTypes < ParamTypes ... > ( std::array < std::string, sizeof ... ( ParamTypes ) > { } );
+
+		unregisterInternal ( std::move ( algorithm ), std::move ( templateParams ), category, std::move ( params ) );
+	}
+
 	template < class Algo, class ObjectType, class ReturnType, class ... ParamTypes >
 	static void registerMethod ( ReturnType ( ObjectType:: * callback ) ( ParamTypes ... ), std::string methodName, std::array < std::string, sizeof ... ( ParamTypes ) > paramNames ) {
 		AlgorithmCategories::AlgorithmCategory category = AlgorithmCategories::AlgorithmCategory::DEFAULT;
diff --git a/alib2common/src/core/components.hpp b/alib2common/src/core/components.hpp
index dd89edae99..c34dd2ad08 100644
--- a/alib2common/src/core/components.hpp
+++ b/alib2common/src/core/components.hpp
@@ -163,6 +163,15 @@ public:
 		abstraction::AlgorithmRegistry::registerMethod < ComponentName > ( setMethod, "set", elementNames );
 	}
 
+	/**
+	 * Register this component's accessors to abstraction
+	 */
+	static void unregisterComponent ( ) {
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived & > ( "get" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, const Derived & > ( "get" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived &, ComponentType > ( "set" );
+	}
+
 };
 
 /**
@@ -182,6 +191,12 @@ public:
 	 */
 	static void registerComponent ( ) {
 	}
+
+	/**
+	 * To silent the compiler about nonexistent access method in Components base
+	 */
+	static void unregisterComponent ( ) {
+	}
 };
 
 /**
@@ -221,6 +236,14 @@ public:
 		Component < Derived, ComponentType, ComponentCategory, ComponentName >::registerComponent ( );
 		Components < Derived, Next ... >::registerComponent ( );
 	}
+
+	/**
+	 * Dispatcher for registration functions in subclasses.
+	 */
+	static void unregisterComponent ( ) {
+		Component < Derived, ComponentType, ComponentCategory, ComponentName >::unregisterComponent ( );
+		Components < Derived, Next ... >::unregisterComponent ( );
+	}
 };
 
 /**
@@ -260,6 +283,14 @@ public:
 		Component < Derived, ComponentType, ComponentCategory, ComponentName >::registerComponent ( );
 		Components < Derived, ComponentType, ComponentCategory, std::tuple < ComponentNames ... >, Next ... >::registerComponent ( );
 	}
+
+	/**
+	 * Dispatcher for registration functions in subclasses.
+	 */
+	static void unregisterComponent ( ) {
+		Component < Derived, ComponentType, ComponentCategory, ComponentName >::unregisterComponent ( );
+		Components < Derived, ComponentType, ComponentCategory, std::tuple < ComponentNames ... >, Next ... >::unregisterComponent ( );
+	}
 };
 
 /**
@@ -292,6 +323,13 @@ public:
 	static void registerComponent ( ) {
 		Components < Derived, Next ... >::registerComponent ( );
 	}
+
+	/**
+	 * Dispatcher for registration functions in subclasses.
+	 */
+	static void unregisterComponent ( ) {
+		Components < Derived, Next ... >::unregisterComponent ( );
+	}
 };
 
 } /* namespace core */
diff --git a/alib2common/src/core/components/setComponents.hpp b/alib2common/src/core/components/setComponents.hpp
index fbef1e2d66..1b836b2467 100644
--- a/alib2common/src/core/components/setComponents.hpp
+++ b/alib2common/src/core/components/setComponents.hpp
@@ -265,6 +265,20 @@ public:
 		bool ( Derived::* emptyMethod ) ( ) const = & SetComponent < Derived, ComponentType, typename ComponentType::value_type, ComponentName >::empty;
 		abstraction::AlgorithmRegistry::registerMethod < ComponentName > ( emptyMethod, "empty", emptyNames );
 	}
+
+	/**
+	 * Register this component's accessors to abstraction
+	 */
+	static void unregisterComponent ( ) {
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived & > ( "get" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, const Derived & > ( "get" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived &, ComponentType > ( "set" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived, typename ComponentType::value_type > ( "add" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived, ComponentType > ( "add" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived, const typename ComponentType::value_type & > ( "remove" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, Derived, const ComponentType & > ( "remove" );
+		abstraction::AlgorithmRegistry::unregisterMethod < ComponentName, const Derived & > ( "empty" );
+	}
 };
 
 } /* namespace core */
diff --git a/alib2xml/src/core/xmlApi.hpp b/alib2xml/src/core/xmlApi.hpp
index a225ba106e..637dd14c9a 100644
--- a/alib2xml/src/core/xmlApi.hpp
+++ b/alib2xml/src/core/xmlApi.hpp
@@ -100,6 +100,11 @@ private:
 	};
 
 public:
+	template < class Type >
+	static void unregisterXmlReader ( ) {
+		parseFunctions ( ).erase ( xmlApi < Type >::xmlTagName ( ) );
+	}
+
 	template < class Type >
 	static void registerXmlReader ( ) {
 		bool res = parseFunctions ( ).insert ( std::make_pair ( xmlApi < Type >::xmlTagName(), std::unique_ptr < GroupParser > ( new ParserRegister < Type > ( ) ) ) ).second;
@@ -111,6 +116,11 @@ public:
 		}
 	}
 
+	template < class Type >
+	static void unregisterXmlWriter ( ) {
+		composeFunctions ( ).erase ( ext::to_string < object::AnyObject < Type > > ( ) );
+	}
+
 	template < class Type >
 	static void registerXmlWriter ( ) {
 		bool res = composeFunctions ( ).insert ( std::make_pair ( ext::to_string < object::AnyObject < Type > > ( ), std::unique_ptr < GroupComposer > ( new ComposerRegister < Type > ( ) ) ) ).second;
-- 
GitLab