From 1bf38d7fc6c62f6ff322fc5b2ebff2433bed4d77 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 30 Jan 2019 15:03:08 +0100
Subject: [PATCH] throw exception on unregistration of non-existent entry

---
 alib2abstraction/src/registry/CastRegistry.hpp    |  3 ++-
 .../src/registry/ContainerRegistry.hpp            |  7 ++++---
 .../src/registry/ImmediateRegistry.hpp            |  3 ++-
 .../src/registry/NormalizeRegistry.hpp            | 11 ++++++++---
 .../src/registry/ValuePrinterRegistry.hpp         |  3 ++-
 alib2raw/src/registry/RawReaderRegistry.hpp       |  3 ++-
 alib2raw/src/registry/RawWriterRegistry.hpp       |  3 ++-
 alib2str/src/core/stringApi.hpp                   | 15 ++++++++++++---
 alib2str/src/registration/StringRegistration.hpp  |  2 +-
 alib2str/src/registry/StringReaderRegistry.hpp    |  9 ++++++++-
 alib2str/src/registry/StringWriterRegistry.hpp    |  3 ++-
 alib2xml/src/core/xmlApi.hpp                      | 14 ++++++++++++--
 alib2xml/src/registry/XmlComposerRegistry.hpp     |  3 ++-
 .../src/registry/XmlContainerParserRegistry.hpp   |  8 +++++---
 alib2xml/src/registry/XmlParserRegistry.hpp       |  3 ++-
 15 files changed, 66 insertions(+), 24 deletions(-)

diff --git a/alib2abstraction/src/registry/CastRegistry.hpp b/alib2abstraction/src/registry/CastRegistry.hpp
index 0e2df9e9cf..0551f714a5 100644
--- a/alib2abstraction/src/registry/CastRegistry.hpp
+++ b/alib2abstraction/src/registry/CastRegistry.hpp
@@ -53,7 +53,8 @@ private:
 
 public:
 	static void unregisterCast ( std::string target, std::string param ) {
-		getEntries ( ).erase ( std::make_pair ( target, param ) );
+		if ( ! getEntries ( ).erase ( std::make_pair ( target, param ) ) )
+			throw std::invalid_argument ( "Entry from " + param + " to " + target + " not registered." );
 	}
 
 	template < class TargetType, class ParamType >
diff --git a/alib2abstraction/src/registry/ContainerRegistry.hpp b/alib2abstraction/src/registry/ContainerRegistry.hpp
index d88509082a..9be92e6428 100644
--- a/alib2abstraction/src/registry/ContainerRegistry.hpp
+++ b/alib2abstraction/src/registry/ContainerRegistry.hpp
@@ -51,8 +51,9 @@ public:
 		auto iter = find_if ( group.begin ( ), group.end ( ), [ & ] ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry ) {
 				return entry.first == param;
 				} );
-		if ( iter != group.end ( ) )
-			group.erase ( iter );
+		if ( iter == group.end ( ) )
+			throw std::invalid_argument ( "Callback for " + param + " in contaier " + container + " not registered." );
+		group.erase ( iter );
 	}
 
 	template < class ParamTypes >
@@ -68,7 +69,7 @@ public:
 		auto & group = getEntries ( ) [ container ];
 		for ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry : group )
 			if ( entry.first == param )
-				throw std::invalid_argument ( "Callback for " + container + " already registered." );
+				throw std::invalid_argument ( "Callback for " + param + " in contaier " + container + " already registered." );
 
 		std::shared_ptr < Entry > entryValue = std::make_shared < SetEntryImpl < ParamTypes > > ( );
 		group.insert ( group.end ( ), ext::make_pair ( param, entryValue ) );
diff --git a/alib2abstraction/src/registry/ImmediateRegistry.hpp b/alib2abstraction/src/registry/ImmediateRegistry.hpp
index 49a2c54c22..3ea17c2bca 100644
--- a/alib2abstraction/src/registry/ImmediateRegistry.hpp
+++ b/alib2abstraction/src/registry/ImmediateRegistry.hpp
@@ -45,7 +45,8 @@ private:
 
 public:
 	static void unregisterImmediate ( std::string result ) {
-		getEntries ( ).erase ( result );
+		if ( ! getEntries ( ).erase ( result ) )
+			throw std::invalid_argument ( "Entry " + result + " not registered." );
 	}
 
 	template < class ResultType >
diff --git a/alib2abstraction/src/registry/NormalizeRegistry.hpp b/alib2abstraction/src/registry/NormalizeRegistry.hpp
index e4a6580caf..bf14b93dbf 100644
--- a/alib2abstraction/src/registry/NormalizeRegistry.hpp
+++ b/alib2abstraction/src/registry/NormalizeRegistry.hpp
@@ -13,6 +13,7 @@
 #include <alib/map>
 #include <alib/list>
 #include <alib/typeinfo>
+#include <alib/algorithm>
 
 #include <abstraction/OperationAbstraction.hpp>
 
@@ -47,15 +48,19 @@ private:
 	static ext::map < std::string, std::list < std::unique_ptr < Entry > > > & getEntries ( );
 
 public:
-	template < class ParamType >
 	static void unregisterNormalize ( std::string param, std::list < std::unique_ptr < Entry > >::const_iterator iter ) {
-		getEntries ( ) [ param ].erase ( iter );
+		auto & entry = getEntries ( ) [ param ];
+
+		if ( ! ext::range_contains_iterator ( entry.begin ( ), entry.end ( ), iter ) )
+			throw std::invalid_argument ( "Normalization entry not found in " + param + "." );
+
+		entry.erase ( iter );
 	}
 
 	template < class ParamType >
 	static void unregisterNormalize ( std::list < std::unique_ptr < Entry > >::const_iterator iter ) {
 		std::string param = ext::to_string < ParamType > ( );
-		unregisterNormalize < ParamType > ( std::move ( param ), iter );
+		unregisterNormalize ( std::move ( param ), iter );
 	}
 
 	template < class ParamType >
diff --git a/alib2abstraction/src/registry/ValuePrinterRegistry.hpp b/alib2abstraction/src/registry/ValuePrinterRegistry.hpp
index 722c21ac43..9c1ee4585f 100644
--- a/alib2abstraction/src/registry/ValuePrinterRegistry.hpp
+++ b/alib2abstraction/src/registry/ValuePrinterRegistry.hpp
@@ -45,7 +45,8 @@ private:
 
 public:
 	static void unregisterValuePrinter ( std::string param ) {
-		getEntries ( ).erase ( param );
+		if ( ! getEntries ( ).erase ( param ) )
+			throw std::invalid_argument ( "Entry " + param + " not registered." );
 	}
 
 	template < class ParamType >
diff --git a/alib2raw/src/registry/RawReaderRegistry.hpp b/alib2raw/src/registry/RawReaderRegistry.hpp
index 2b1f141c52..6e75a22953 100644
--- a/alib2raw/src/registry/RawReaderRegistry.hpp
+++ b/alib2raw/src/registry/RawReaderRegistry.hpp
@@ -42,7 +42,8 @@ private:
 
 public:
 	static void unregisterRawReader ( std::string type ) {
-		getEntries ( ).erase ( type );
+		if ( ! getEntries ( ).erase ( type ) )
+			throw std::invalid_argument ( "Entry " + type + " not registered." );
 	}
 
 	template < class ReturnType >
diff --git a/alib2raw/src/registry/RawWriterRegistry.hpp b/alib2raw/src/registry/RawWriterRegistry.hpp
index 5c5eae33cc..2ecfcf3258 100644
--- a/alib2raw/src/registry/RawWriterRegistry.hpp
+++ b/alib2raw/src/registry/RawWriterRegistry.hpp
@@ -45,7 +45,8 @@ private:
 
 public:
 	static void unregisterRawWriter ( std::string param ) {
-		getEntries ( ).erase ( param );
+		if ( ! getEntries ( ).erase ( param ) )
+			throw std::invalid_argument ( "Entry " + param + " not registered." );
 	}
 
 	template < class ParamType >
diff --git a/alib2str/src/core/stringApi.hpp b/alib2str/src/core/stringApi.hpp
index 6e6113a8f3..86e28d23c1 100644
--- a/alib2str/src/core/stringApi.hpp
+++ b/alib2str/src/core/stringApi.hpp
@@ -16,6 +16,7 @@
 #include <alib/algorithm>
 #include <alib/istream>
 #include <alib/typeinfo>
+#include <alib/algorithm>
 
 #include <object/Object.h>
 #include <object/AnyObject.h>
@@ -74,9 +75,12 @@ private:
 	};
 
 public:
-	template < class Type >
 	static void unregisterStringReader ( ext::list < std::pair < std::function < bool ( std::istream & ) >, std::unique_ptr < GroupReader > > >::const_iterator iter ) {
-		parseFunctions ( ).erase ( iter );
+		auto & entry = parseFunctions ( );
+		if ( ! ext::range_contains_iterator ( entry.begin ( ), entry.end ( ), iter ) )
+			throw std::invalid_argument ( "Entry not found." );
+
+		entry.erase ( iter );
 	}
 
 	template < class Type >
@@ -87,7 +91,12 @@ public:
 
 	template < class Type >
 	static void unregisterStringWriter ( ) {
-		composeFunctions ( ).erase ( ext::to_string < object::AnyObject < Type > > ( ) );
+		if ( ! composeFunctions ( ).erase ( ext::to_string < object::AnyObject < Type > > ( ) ) ) {
+			std::string groupName = ext::to_string < object::Object > ( );
+			std::string typeName = ext::to_string < Type > ( );
+
+			throw::exception::CommonException ( "Parse callback of " + typeName + " not registered in group " + groupName + "." );
+		}
 	}
 
 	template < class Type >
diff --git a/alib2str/src/registration/StringRegistration.hpp b/alib2str/src/registration/StringRegistration.hpp
index b09428bbf2..ca3ee90299 100644
--- a/alib2str/src/registration/StringRegistration.hpp
+++ b/alib2str/src/registration/StringRegistration.hpp
@@ -82,7 +82,7 @@ public:
 	}
 
 	~StringReaderRegisterTypeInGroup ( ) {
-		core::stringApi < Group >::template unregisterStringReader < Type > ( iter );
+		core::stringApi < Group >::unregisterStringReader ( iter );
 	}
 };
 
diff --git a/alib2str/src/registry/StringReaderRegistry.hpp b/alib2str/src/registry/StringReaderRegistry.hpp
index b8feb2f1c1..14ae779052 100644
--- a/alib2str/src/registry/StringReaderRegistry.hpp
+++ b/alib2str/src/registry/StringReaderRegistry.hpp
@@ -11,6 +11,7 @@
 #include <alib/memory>
 #include <alib/string>
 #include <alib/map>
+#include <alib/algorithm>
 
 #include <exception/CommonException.h>
 #include <abstraction/OperationAbstraction.hpp>
@@ -48,7 +49,13 @@ public:
 	static void unregisterStringReader ( ext::list < std::pair < std::function < bool ( std::istream & ) >, std::unique_ptr < Entry > > >::const_iterator iter ) {
 		std::string group = ext::to_string < Group > ( );
 
-		getEntries ( ) [ group ].erase ( iter );
+		auto & entry = getEntries ( ) [ group ];
+		if ( ! ext::range_contains_iterator ( entry.begin ( ), entry.end ( ), iter ) )
+			throw std::invalid_argument ( "Entry not found in " + group + "." );
+
+		entry.erase ( iter );
+		if ( entry.size ( ) == 0 )
+			getEntries ( ).erase ( group );
 	}
 
 	template < class Group, class ReturnType >
diff --git a/alib2str/src/registry/StringWriterRegistry.hpp b/alib2str/src/registry/StringWriterRegistry.hpp
index 85b0757d7e..1f98bb991d 100644
--- a/alib2str/src/registry/StringWriterRegistry.hpp
+++ b/alib2str/src/registry/StringWriterRegistry.hpp
@@ -46,7 +46,8 @@ private:
 
 public:
 	static void unregisterStringWriter ( std::string param ) {
-		getEntries ( ).erase ( param );
+		if ( ! getEntries ( ).erase ( param ) )
+			throw std::invalid_argument ( "Entry " + param + " not registered." );
 	}
 
 	template < class ParamType >
diff --git a/alib2xml/src/core/xmlApi.hpp b/alib2xml/src/core/xmlApi.hpp
index 08ee579c07..0ec6a3a6e2 100644
--- a/alib2xml/src/core/xmlApi.hpp
+++ b/alib2xml/src/core/xmlApi.hpp
@@ -105,7 +105,12 @@ private:
 public:
 	template < class Type >
 	static void unregisterXmlReader ( ) {
-		parseFunctions ( ).erase ( xmlApi < Type >::xmlTagName ( ) );
+		if ( ! parseFunctions ( ).erase ( xmlApi < Type >::xmlTagName ( ) ) ) {
+			std::string groupName = ext::to_string < object::Object > ( );
+			std::string typeName = ext::to_string < Type > ( );
+
+			throw::exception::CommonException ( "Parse callback of " + typeName + " not registered in group " + groupName + "." );
+		}
 	}
 
 	template < class Type >
@@ -121,7 +126,12 @@ public:
 
 	template < class Type >
 	static void unregisterXmlWriter ( ) {
-		composeFunctions ( ).erase ( ext::to_string < object::AnyObject < Type > > ( ) );
+		if ( ! composeFunctions ( ).erase ( ext::to_string < object::AnyObject < Type > > ( ) ) ) {
+			std::string groupName = ext::to_string < object::Object > ( );
+			std::string typeName = ext::to_string < Type > ( );
+
+			throw::exception::CommonException ( "Compose callback of " + typeName + " not registered in group " + groupName + "." );
+		}
 	}
 
 	template < class Type >
diff --git a/alib2xml/src/registry/XmlComposerRegistry.hpp b/alib2xml/src/registry/XmlComposerRegistry.hpp
index 562b7b3e8f..fb5c96b6ee 100644
--- a/alib2xml/src/registry/XmlComposerRegistry.hpp
+++ b/alib2xml/src/registry/XmlComposerRegistry.hpp
@@ -46,7 +46,8 @@ private:
 
 public:
 	static void unregisterXmlComposer ( std::string param ) {
-		getEntries ( ).erase ( param );
+		if ( ! getEntries ( ).erase ( param ) )
+			throw std::invalid_argument ( "Entry " + param + " not registered." );
 	}
 
 	template < class ParamType >
diff --git a/alib2xml/src/registry/XmlContainerParserRegistry.hpp b/alib2xml/src/registry/XmlContainerParserRegistry.hpp
index a97d897bed..4d1f6fbbb6 100644
--- a/alib2xml/src/registry/XmlContainerParserRegistry.hpp
+++ b/alib2xml/src/registry/XmlContainerParserRegistry.hpp
@@ -51,8 +51,10 @@ public:
 		auto iter = find_if ( group.begin ( ), group.end ( ), [ & ] ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry ) {
 				return entry.first == param;
 				} );
-		if ( iter != group.end ( ) )
-			group.erase ( iter );
+		if ( iter == group.end ( ) )
+			throw exception::CommonException ( "Callback for " + param + " in container " + container + " not registered." );
+
+		group.erase ( iter );
 	}
 
 	template < class ParamTypes >
@@ -68,7 +70,7 @@ public:
 		auto & group = getEntries ( ) [ container ];
 		for ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry : group )
 			if ( entry.first == param )
-				throw exception::CommonException ( "Callback for " + container + " already registered." );
+				throw exception::CommonException ( "Callback for " + param + " in container " + container + " already registered." );
 
 		std::shared_ptr < Entry > entryValue = std::make_shared < SetEntryImpl < ParamTypes > > ( );
 		group.insert ( group.end ( ), ext::make_pair ( param, entryValue ) );
diff --git a/alib2xml/src/registry/XmlParserRegistry.hpp b/alib2xml/src/registry/XmlParserRegistry.hpp
index 3a8cb7b52b..35028ee6c9 100644
--- a/alib2xml/src/registry/XmlParserRegistry.hpp
+++ b/alib2xml/src/registry/XmlParserRegistry.hpp
@@ -45,7 +45,8 @@ private:
 
 public:
 	static void unregisterXmlParser ( std::string result ) {
-		getEntries ( ).erase ( result );
+		if ( ! getEntries ( ).erase ( result ) )
+			throw std::invalid_argument ( "Entry " + result + " not registered." );
 	}
 
 	template < class ReturnType >
-- 
GitLab