summaryrefslogtreecommitdiff
path: root/include/util/TypeInfo.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/util/TypeInfo.hpp')
-rwxr-xr-xinclude/util/TypeInfo.hpp82
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