diff options
Diffstat (limited to 'include/util/TypeInfo.hpp')
-rwxr-xr-x | include/util/TypeInfo.hpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/include/util/TypeInfo.hpp b/include/util/TypeInfo.hpp new file mode 100755 index 0000000..3ca4b57 --- /dev/null +++ b/include/util/TypeInfo.hpp @@ -0,0 +1,82 @@ +#ifndef __TYPEINFO_H +#define __TYPEINFO_H + +#include <typeinfo> +#include <string> +#include <stdexcept> +#include <cstdlib> + +#if defined( __GNUG__ ) && defined( __GLIBCXX__ ) + +#include <cxxabi.h> + +std::string demangle( const std::type_info &info ) +{ + enum { BUFLEN = 200 }; + char *buf; + std::size_t buflen = BUFLEN; + int status; + char *res; + + // pass a malloced buffer (required by cxa_demangle) + buf = (char *)malloc( BUFLEN ); + + // res may point to buf or be realloced depending on whether the + // demangling had enough space or not + res = __cxxabiv1::__cxa_demangle( info.name( ), buf, &buflen, &status ); + + // throw exception if this goes wrong, because we don't want to have + // have code reacting on failed demangling or wrong type information! + if( status != 0 || res == NULL ) { + throw std::runtime_error( "__cxa_demangle failed!" ); + } + + // construct string on stack and return it, free original buffer + std::string s( res ); + free( res ); + + return s; +} + +#else + +#ifdef _WIN32 + +// TODO: maybe extract into a generic stringutils module +void replaceAll( std::string &s, const std::string &from, const std::string &to ) +{ + if( from.empty( ) ) { + return; + } + + size_t pos = 0; + while( ( pos = s.find( from, pos ) ) != std::string::npos ) { + s.replace( pos, from.length( ), to ); + pos += to.length( ); + } +} + +std::string demangle( const std::type_info &info ) +{ + std::string name = info.name( ); + + // MSVC marks metatypes, nice, but gcc doesn't, falling + // back as we can't do the same for gcc + replaceAll( name, "class ", "" ); + // TODO: much more to follow, this is currently just enough + // for the module registry structure with base class + // signature only + + return name; +} + +#else + +#error "type.name() demangling not implemented!" + +#endif // _WIN32 + + +#endif // defined( __GNUG__ ) && defined( __GLIBCXX__ ) + +#endif // __TYPEINFO_H |