Skip to content

Instantly share code, notes, and snippets.

@schaumb
Last active May 14, 2024 18:58
Show Gist options
  • Save schaumb/d036ab04df35550866577edea51f7f10 to your computer and use it in GitHub Desktop.
Save schaumb/d036ab04df35550866577edea51f7f10 to your computer and use it in GitHub Desktop.
c++ get member name from member pointer
// see at godbolt : https://godbolt.org/z/zMGEGs99v
#include <string_view>
template<auto V>
constexpr static auto n() noexcept {
#ifdef _MSC_VER
std::string_view sv = __FUNCSIG__;
auto to = sv.rfind('>')-1;
for (std::size_t close = sv[to] == ')'; close > 0; ) {
switch(sv[to = sv.find_last_of(")(", to-1)]) {
case ')': ++close; break;
case '(': if (!--close) --to; break;
}
}
for (std::size_t close = sv[to] == '>'; close > 0; ) {
switch(sv[to = sv.find_last_of("><", to-1)]) {
case '>': ++close; break;
case '<': if (!--close) --to; break;
}
}
auto from = sv.find_last_of(">:", to);
return sv.substr(from + 1, to - from);
#else
std::string_view sv = __PRETTY_FUNCTION__;
auto from = sv.rfind(':');
return sv.substr(from + 1, sv.size() - 2 - from);
#endif
}
template<class From, class Type>
From get_base_type(Type From::*);
template<class T>
union union_type {
char c;
T f;
constexpr union_type() : c{} {}
};
template<class T>
constexpr extern T constexpr_static_init {};
template<auto V>
constexpr static std::string_view get_name_if_exists() noexcept {
if constexpr (std::is_member_function_pointer_v<decltype(V)>) {
return n<V>();
} else {
#ifdef _MSC_VER
# if _MSVC_LANG >= 202000
return n<&(constexpr_static_init<
union_type<decltype(get_base_type(V))>
>.f.*V)>();
# else // if_MSVC_LANG < 202000
return "";
# endif // _MSVC_LANG >= 202000
#else // if !defined(_MSC_VER)
return n<V>();
#endif // _MSC_VER
}
}
template<auto N>
constexpr auto get_name(std::string_view name = get_name_if_exists<N>()) {
return name;
}
@Desp4
Copy link

Desp4 commented May 14, 2024

I see, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment