diff options
-rw-r--r-- | entity/name-of.hpp | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/entity/name-of.hpp b/entity/name-of.hpp index 42674a19..fcde3d46 100644 --- a/entity/name-of.hpp +++ b/entity/name-of.hpp @@ -1,5 +1,6 @@ #pragma once -#include <Corrade/Containers/StringView.h> +#include "compat/assert.hpp" +#include <cr/StringView.h> #if defined _MSC_VER #define FM_PRETTY_FUNCTION __FUNCSIG__ @@ -8,8 +9,10 @@ #endif template<typename T> -static constexpr auto mangled_name() { // NOLINT(bugprone-reserved-identifier) - using namespace Corrade::Containers; +static constexpr auto _fm_internal_type_name_of() +{ + // NOLINT(bugprone-reserved-identifier) + using namespace floormat; using SVF = StringViewFlag; constexpr auto my_strlen = [](const char* str) constexpr -> size_t { const char* start = str; @@ -17,8 +20,60 @@ static constexpr auto mangled_name() { // NOLINT(bugprone-reserved-identifier) ; return (size_t)(str - start); }; + constexpr auto strip_prefix = [](StringView& s, StringView pfx) constexpr { + if (s.size() < pfx.size()) + return false; + for (auto i = 0uz; i < pfx.size(); i++) + if (s[i] != pfx[i]) + return false; + s = StringView{ s.data() + pfx.size(), s.size() - pfx.size(), s.flags() }; + return true; + }; + constexpr auto strip_suffix = [](StringView& s, StringView suffix) constexpr { + if (s.size() < suffix.size()) + return false; + const auto ssiz = s.size(), sufsiz = suffix.size(); + for (auto i = 0uz; i < sufsiz; i++) + if (s[ssiz - 1 - i] != suffix[sufsiz - 1 - i]) + return false; + s = StringView{ s.data(), ssiz - sufsiz, s.flags() }; + return true; + }; const char* str = FM_PRETTY_FUNCTION; - return StringView { str, my_strlen(str), SVF::Global|SVF::NullTerminated }; + auto s = StringView{ str, my_strlen(str), SVF::Global|SVF::NullTerminated }; + strip_prefix(s, "constexpr "_s); + + if (strip_prefix(s, "auto "_s)) + { +#ifdef _WIN32 + strip_prefix(s, "__cdecl "_s); +#endif +#ifdef _MSC_VER + if (strip_prefix(s, "_fm_internal_type_name_of<"_s)) + { + strip_prefix(s, "struct "_s) || strip_prefix(s, "class "_s); + strip_suffix(s, "(void)"_s); + bool ret = strip_suffix(s, ">"_s); + fm_assert(ret); + // todo s/\b(?:class|struct)\b//g + } +#endif +#if defined __GNUG__ || defined __clang__ + if (strip_prefix(s, "_fm_internal_type_name_of()"_s)) + { + if (strip_prefix(s, " [with T = "_s) || strip_prefix(s, " [T = "_s)) + { + bool ret = strip_suffix(s, "]"_s); + fm_assert(ret); + } + } +#endif + } + return s; } -template<typename T> constexpr inline auto name_of = mangled_name<T>(); +namespace floormat { + +template<typename T> constexpr StringView name_of = ::_fm_internal_type_name_of<T>(); + +} // namespace floormat |