meta/runtime/meta_utils.h
2024-03-06 09:01:30 +08:00

68 lines
1.7 KiB
C++

#pragma once
#ifndef META_RUNTIME_META_UTILS_H
#define META_RUNTIME_META_UTILS_H
#include <cxxabi.h>
#include <string>
namespace meta {
namespace {
template<typename T>
inline std::string
GetDemangleName()
{
const std::string name = typeid(T).name();
std::string pretty_name = name;
int status = -4;
char *res = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
if (status == 0) { pretty_name = std::string(res); }
free(res);
return pretty_name;
}
inline std::string
RemoveWhiteSpace(const std::string &name, const std::string &chars = "[]<>,&* ")
{
// trim left and right
std::string compact_name = name.substr(name.find_first_not_of(' '));
compact_name = compact_name.substr(0, compact_name.find_last_not_of(' ') + 1);
// remove white space
for (int i = 0; i < compact_name.size(); ++i) {
if (compact_name[i] == ' ') {
if (i > 0 && chars.find(compact_name[i - 1]) != std::string::npos) {
compact_name.erase(i, 1);
} else if (i + 1 < compact_name.size() && chars.find(compact_name[i + 1]) != std::string::npos) {
compact_name.erase(i, 1);
}
}
}
return compact_name;
}
inline std::string
RemoveInnerNamespace(const std::string &name)
{
std::string new_name = name;
while (true) {
auto iter = name.find("::__1::");
if (iter == std::string::npos) { break; }
new_name.replace(iter, 5, "::");
}
return new_name;
}
}// namespace
template<typename T>
std::string
GetMetaName()
{
static std::string name = RemoveInnerNamespace(RemoveWhiteSpace(GetDemangleName<T>()));
return name;
}
}// namespace meta
#endif// META_RUNTIME_META_UTILS_H