diff --git a/alib2common/src/cast/CastApi.hpp b/alib2common/src/cast/CastApi.hpp index d199ae6d03925f1e2b4288ca1e974e28d84c55d8..a0750734db2eb277c288f5ddd7eb38ccac9b85e9 100644 --- a/alib2common/src/cast/CastApi.hpp +++ b/alib2common/src/cast/CastApi.hpp @@ -11,9 +11,11 @@ #include <functional> #include <map> #include <string> +#include <type_traits> #include "../object/ObjectBase.h" #include "../object/Object.h" +#include "../exception/CommonException.h" namespace alib { @@ -22,12 +24,22 @@ struct castApi { protected: std::map < std::type_index, std::function < alib::Object ( const alib::ObjectBase & ) > > castFunctions; + virtual std::string toType ( ) = 0; + public: + virtual ~CastPoolBase() { + } + alib::Object cast ( const alib::ObjectBase & from ) { std::map < std::type_index, std::function < alib::Object ( const alib::ObjectBase & ) > >::iterator res = castFunctions.find ( std::type_index ( typeid ( from ) ) ); - if ( res == castFunctions.end ( ) ) - throw std::bad_cast ( ); + if ( res == castFunctions.end ( ) ) { + char* name = std::type_name(typeid(from)); + std::string fromType(name); + std::free(name); + + throw exception::CommonException ( "Bad cast: From: " + fromType + " To: " + toType()); + } return res->second ( from ); } @@ -59,6 +71,13 @@ struct castApi { return castFunctions.count ( std::type_index ( typeid ( From ) ) ); } + std::string toType ( ) { + char* name = std::type_name<To>(); + std::string toType(name); + std::free(name); + return toType; + } + }; private: @@ -103,7 +122,7 @@ public: std::map < std::string, CastPoolBase * >::iterator res = castFunctionsByString ( ).find ( tagName ); if ( res == castFunctionsByString ( ).end ( ) ) - throw std::invalid_argument ( "Casting to type " + tagName + " not available." ); + throw exception::CommonException ( "Casting to type " + tagName + " not available." ); else return * res->second; } @@ -111,9 +130,13 @@ public: static CastPoolBase & getCastPool ( std::type_index typeId ) { std::map < std::type_index, CastPoolBase * >::iterator res = castFunctionsById ( ).find ( typeId ); - if ( res == castFunctionsById ( ).end ( ) ) - throw std::invalid_argument ( "Casting to type ? not available." ); - else + if ( res == castFunctionsById ( ).end ( ) ) { + char* name = std::type_name( typeId ); + std::string toType(name); + std::free(name); + + throw exception::CommonException ( "Casting to type " + toType + " not available." ); + } else return * res->second; } diff --git a/alib2std/src/extensions/type_traits.cpp b/alib2std/src/extensions/type_traits.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d30d3ae2ea3829d581082662043bb184de47c64 --- /dev/null +++ b/alib2std/src/extensions/type_traits.cpp @@ -0,0 +1,23 @@ +/* + * istream.cpp + * + * Created on: Apr 14, 2016 + * Author: Jan Travnicek + */ + +#include "../type_traits" + +namespace std { + + char* type_name(const std::type_info& type) { + int status; + + return abi::__cxa_demangle(type.name(), 0, 0, &status); + } + + char* type_name(const std::type_index& type) { + int status; + + return abi::__cxa_demangle(type.name(), 0, 0, &status); + } +} diff --git a/alib2std/src/extensions/type_traits.hpp b/alib2std/src/extensions/type_traits.hpp index 9b1a406120cb87357b1bfffc6ea1350428434c35..6987b19824038a462d93397a07543c5aee2defef 100644 --- a/alib2std/src/extensions/type_traits.hpp +++ b/alib2std/src/extensions/type_traits.hpp @@ -56,6 +56,9 @@ namespace std { return abi::__cxa_demangle(typeid(T).name(), 0, 0, &status); } + char* type_name(const std::type_info& type); + char* type_name(const std::type_index& type); + } /* namespace std */ #endif // TYPE_TRAITS_HPP_ diff --git a/alib2std/src/type_traits b/alib2std/src/type_traits index b324d36ac346cb9a68dfa21f5862f5b258261e4f..1fcebfe8698edd502d5f8e75bb594ae4c88caeb5 100644 --- a/alib2std/src/type_traits +++ b/alib2std/src/type_traits @@ -6,6 +6,7 @@ #include <cstdio> #include <cstdlib> #include <cstring> +#include <typeindex> #include "extensions/type_traits.hpp" #endif /* __TYPE_TRAITS_HEADER_WRAPPER_ */