From d105ddf665e820a57431c7dbee8db57fa2d84c46 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 12 Mar 2017 21:30:22 +0100
Subject: [PATCH] casts introspection

---
 aintrospection2/src/aintrospection.cpp  | 23 +++++++++++++++
 alib2common/src/core/castApi.hpp        |  6 ++++
 alib2common/src/introspection/Casts.hpp | 37 +++++++++++++++++++++++++
 3 files changed, 66 insertions(+)

diff --git a/aintrospection2/src/aintrospection.cpp b/aintrospection2/src/aintrospection.cpp
index 94b49c5c09..aa753976e7 100644
--- a/aintrospection2/src/aintrospection.cpp
+++ b/aintrospection2/src/aintrospection.cpp
@@ -13,6 +13,7 @@
 
 #include <introspection/DataTypes.hpp>
 #include <introspection/Algorithms.hpp>
+#include <introspection/Casts.hpp>
 
 int main ( int argc, char * argv[] ) {
 	try {
@@ -36,6 +37,12 @@ int main ( int argc, char * argv[] ) {
 		TCLAP::ValueArg < std::string > algorithmCallbacks ( "a", "algorithm_callbacks", "Algorithm Callbacks", false, "", "string" );
 		cmd.add ( algorithmCallbacks );
 
+		TCLAP::ValueArg < std::string > castFrom ( "", "cast_from", "Casting handlers from type", false, "", "string" );
+		cmd.add ( castFrom );
+
+		TCLAP::ValueArg < std::string > castTo ( "", "cast_to", "Casting handlers to type", false, "", "string" );
+		cmd.add ( castTo );
+
 		TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false );
 		cmd.add ( measure );
 
@@ -84,6 +91,22 @@ int main ( int argc, char * argv[] ) {
 				for ( const auto & callback : algorithmCallbacksIter->second )
 					std::cout << callback << std::endl;
 
+		} else if ( castFrom.isSet ( ) ) {
+			auto fromIter = introspection::Casts::getCastsFrom ( ).find ( castFrom.getValue ( ) );
+			if ( fromIter == introspection::Casts::getCastsFrom ( ).end ( ) || fromIter->second.empty ( ) )
+				std::cout << "No cast from " << castFrom.getValue ( ) << " registered" << std::endl;
+			else
+				for ( const std::string & castTarget : fromIter->second )
+					std::cout << castTarget << std::endl;
+
+		} else if ( castTo.isSet ( ) ) {
+			auto toIter = introspection::Casts::getCastsTo ( ).find ( castTo.getValue ( ) );
+			if ( toIter == introspection::Casts::getCastsTo ( ).end ( ) || toIter->second.empty ( ) )
+				std::cout << "No cast to " << castTo.getValue ( ) << " registered" << std::endl;
+			else
+				for ( const std::string & castSource : toIter->second )
+					std::cout << castSource << std::endl;
+
 		}
 
 		measurements::end ( );
diff --git a/alib2common/src/core/castApi.hpp b/alib2common/src/core/castApi.hpp
index 3afa288d3c..395437046e 100644
--- a/alib2common/src/core/castApi.hpp
+++ b/alib2common/src/core/castApi.hpp
@@ -17,6 +17,8 @@
 #include "../object/Object.h"
 #include "../exception/CommonException.h"
 
+#include <introspection/Casts.hpp>
+
 namespace alib {
 
 struct castApi {
@@ -60,6 +62,8 @@ struct castApi {
 
 				throw::exception::CommonException ( "Casting from " + fromName + " to " + toName + " already registered." );
 			}
+
+			introspection::Casts::registerCast < From, To > ( );
 		}
 
 		template < class From >
@@ -73,6 +77,8 @@ struct castApi {
 
 				throw::exception::CommonException ( "Casting from " + fromName + " to " + toName + " already registered." );
 			}
+
+			introspection::Casts::registerCast < From, To > ( );
 		}
 
 		template < class From >
diff --git a/alib2common/src/introspection/Casts.hpp b/alib2common/src/introspection/Casts.hpp
index b8b9a83968..f1c6a0af55 100644
--- a/alib2common/src/introspection/Casts.hpp
+++ b/alib2common/src/introspection/Casts.hpp
@@ -8,8 +8,45 @@
 #ifndef CASTS_HPP_
 #define CASTS_HPP_
 
+#include <string>
+#include <set>
+#include <map>
+#include <typeinfo>
+
 namespace introspection {
 
+class Casts {
+	static std::map < std::string, std::set < std::string > > & castsFrom ( ) {
+		static std::map < std::string, std::set < std::string > > res;
+		return res;
+	}
+
+	static std::map < std::string, std::set < std::string > > & castsTo ( ) {
+		static std::map < std::string, std::set < std::string > > res;
+		return res;
+	}
+
+public:
+	static const std::map < std::string, std::set < std::string > > & getCastsFrom ( ) {
+		return castsFrom ( );
+	}
+
+	static const std::map < std::string, std::set < std::string > > & getCastsTo ( ) {
+		return castsTo ( );
+	}
+
+	template < class From, class To >
+	static void registerCast ( ) {
+		std::string fromType = std::type_name < From > ( );
+		std::string toType = std::type_name < To > ( );
+
+		std::set < std::string > & fromToSet = Casts::castsFrom ( ) [ fromType ];
+		std::set < std::string > & toFromSet = Casts::castsTo ( ) [ toType ];
+		fromToSet.insert ( std::move ( toType ) );
+		toFromSet.insert ( std::move ( fromType ) );
+	}
+
+};
 
 } /* namespace introspection */
 
-- 
GitLab