Add Nameof helper utility

This commit is contained in:
Wojtek Figat
2021-06-17 14:09:01 +02:00
parent 4de3d134c9
commit f0cb979c5e

View File

@@ -0,0 +1,95 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/StringView.h"
// Helper utility to get type name at compile time. Example:
// constexpr StringAnsiView name = Nameof::Get<PlatformType>()
namespace Nameof
{
// [Reference: https://github.com/Neargye/nameof]
constexpr StringAnsiView PrettyName(StringAnsiView name) noexcept
{
if (name.Length() >= 1 && (name.Get()[0] == '"' || name.Get()[0] == '\''))
return {};
if (name.Length() >= 2 && name.Get()[0] == 'R' && (name.Get()[1] == '"' || name.Get()[1] == '\''))
return {};
if (name.Length() >= 2 && name.Get()[0] == 'L' && (name.Get()[1] == '"' || name.Get()[1] == '\''))
return {};
if (name.Length() >= 2 && name.Get()[0] == 'U' && (name.Get()[1] == '"' || name.Get()[1] == '\''))
return {};
if (name.Length() >= 2 && name.Get()[0] == 'u' && (name.Get()[1] == '"' || name.Get()[1] == '\''))
return {};
if (name.Length() >= 3 && name.Get()[0] == 'u' && name.Get()[1] == '8' && (name.Get()[2] == '"' || name.Get()[2] == '\''))
return {};
if (name.Length() >= 1 && (name.Get()[0] >= '0' && name.Get()[0] <= '9'))
return {};
for (int32 i = name.Length(), h = 0, s = 0; i > 0; --i)
{
if (name.Get()[i - 1] == ')')
{
++h;
++s;
continue;
}
if (name.Get()[i - 1] == '(')
{
--h;
++s;
continue;
}
if (h == 0)
{
name = StringAnsiView(*name, name.Length() - s);
break;
}
++s;
}
int32 s = 0;
for (int32 i = name.Length(), h = 0; i > 0; --i)
{
if (name.Get()[i - 1] == '>')
{
++h;
++s;
continue;
}
if (name.Get()[i - 1] == '<')
{
--h;
++s;
continue;
}
if (h == 0)
break;
++s;
}
for (int32 i = name.Length() - s; i > 0; --i)
{
if (!((name.Get()[i - 1] >= '0' && name.Get()[i - 1] <= '9') || (name.Get()[i - 1] >= 'a' && name.Get()[i - 1] <= 'z') || (name.Get()[i - 1] >= 'A' && name.Get()[i - 1] <= 'Z') || (name.Get()[i - 1] == '_')))
{
name = StringAnsiView(*name + i, name.Length() - i);
break;
}
}
name = StringAnsiView(*name, name.Length() - s);
if (name.Length() > 0 && ((name.Get()[0] >= 'a' && name.Get()[0] <= 'z') || (name.Get()[0] >= 'A' && name.Get()[0] <= 'Z') || (name.Get()[0] == '_')))
return name;
return {};
}
// Gets the type name as constant expression (compile-time string)
template<typename T>
constexpr StringAnsiView Get() noexcept
{
#if defined(__clang__) || defined(__GNUC__)
return PrettyName(StringAnsiView(__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2));
#elif defined(_MSC_VER)
return PrettyName(StringAnsiView(__FUNCSIG__, sizeof(__FUNCSIG__) - 17));
#else
#error "Unsupported compiler."
#endif
}
}