diff --git a/libsrc/core/utils.cpp b/libsrc/core/utils.cpp index cfa3fef8..7b4a97b9 100644 --- a/libsrc/core/utils.cpp +++ b/libsrc/core/utils.cpp @@ -4,10 +4,45 @@ #ifndef WIN32 #include #endif +#include #include +#include namespace ngcore { + namespace detail + { + // see https://github.com/RobotLocomotion/drake/blob/master/common/nice_type_name.cc + static const auto demangle_regexes = + std::array, 8>{ + // Remove unwanted keywords and following space. (\b is word boundary.) + std::make_pair(std::regex("\\b(class|struct|enum|union) "), ""), + // Tidy up anonymous namespace. + {std::regex("[`(]anonymous namespace[')]"), "(anonymous)"}, + // Replace Microsoft __int64 with long long. + {std::regex("\\b__int64\\b"), "long long"}, + // Temporarily replace spaces we want to keep with "!". (\w is + // alphanumeric or underscore.) + {std::regex("(\\w) (\\w)"), "$1!$2"}, + {std::regex(" "), ""}, // Delete unwanted spaces. + // Some compilers throw in extra namespaces like "__1" or "__cxx11". + // Delete them. + {std::regex("\\b__[[:alnum:]_]+::"), ""}, + {std::regex("!"), " "}, // Restore wanted spaces. + + // Recognize std::string's full name and abbreviate. + {std::regex("\\bstd::basic_string," + "std::allocator>"), "std::string"} + }; + std::string CleanupDemangledName( std::string s ) + { + for(const auto & [r, sub] : demangle_regexes) + s = std::regex_replace (s,r,sub); + + return s; + } + } // namespace detail + // parallel netgen int id = 0, ntasks = 1; @@ -15,12 +50,7 @@ namespace ngcore // windows does demangling in typeid(T).name() NGCORE_API std::string Demangle(const char* typeinfo) { std::string name = typeinfo; - // remove "class " and "struct " at beginning of type names to be consistent with demangled names of gcc/clang - if(name.find("class ") == 0) - name.erase(0,6); - if(name.find("struct ") == 0) - name.erase(0,7); - return name; + return detail::CleanupDemangledName(name); } #else NGCORE_API std::string Demangle(const char* typeinfo) @@ -31,13 +61,15 @@ namespace ngcore char *s = abi::__cxa_demangle(typeinfo, nullptr, nullptr, &status); std::string result{s}; free(s); + result = detail::CleanupDemangledName(result); return result; } catch( const std::exception & e ) { GetLogger("utils")->warn("{}:{} cannot demangle {}, status: {}, error:{}", __FILE__, __LINE__, typeinfo, status, e.what()); } - return typeinfo; + std::string name = typeinfo; + return detail::CleanupDemangledName(name); } #endif