zengine/engine/modules/engine/zlib/include/refl/detail/name.inl
2024-07-24 14:42:14 +08:00

95 lines
2.3 KiB
C++

#include "name.h"
namespace refl {
namespace detail {
template<typename T>
constexpr auto func_signature_impl() noexcept {
# if defined(__clang__)
return std::string_view{ __PRETTY_FUNCTION__ };
# elif defined(__GNUC__)
return std::string_view{ __PRETTY_FUNCTION__ };
# elif defined(_MSC_VER)
return std::string_view{ __FUNCSIG__ };
# endif
}
template<size_t N, size_t M>
constexpr auto concat(const TStr<N>& lhs, const TStr<M>& rhs) {
constexpr size_t L = N + M - 1;
char result[L] = {};
for (size_t i = 0; i < L; ++i) {
result[i] = i < N - 1 ? lhs.value[i] : rhs.value[i - N + 1];
}
return TStr<L>{result};
}
constexpr int _num_digits(int num) {
return num < 10 ? 1 : 1 + _num_digits(num / 10);
}
template <int N, int Digits = _num_digits(N)>
constexpr auto num_name() {
char data[Digits + 1];
int n = N;
for (int i = Digits - 1; i >= 0; --i) {
data[i] = static_cast<char>('0' + n % 10);
n /= 10;
}
data[Digits] = '\0'; // null-terminated string
return TStr{ data };
}
template<typename T>
constexpr auto num_prefix_name() {
if constexpr (std::is_integral_v<T>) {
if constexpr (std::is_signed_v<T>) {
return TStr{ "S" };
}
else {
return TStr{ "U" };
}
}
else if constexpr (std::is_floating_point_v<T>) {
return TStr{ "F" };
}
else {
return TStr{ "D" };
}
}
}
template<auto v>
constexpr auto value_name()noexcept {
using T = decltype(v);
if constexpr (std::is_null_pointer_v<T>)
return TStr{ "nullptr" };
else if constexpr (std::is_pointer_v<T>) {
if constexpr (v == nullptr)
return TStr{ "nullptr" };
else
static_assert("not support");
}
else if constexpr (std::is_integral_v<T>) {
if constexpr (std::is_same_v<T, bool>) {
if constexpr (v == true)
return TStr{ "true" };
else
return TStr{ "false" };
}
else {
return TStr{ "false" };
}
}
}
template<typename T>
constexpr auto type_name() noexcept {
if constexpr (std::is_same_v<T, void>) {
return TStr{ "void" };
}
else if constexpr (std::is_arithmetic_v<T>) {
constexpr auto prefix = detail::num_prefix_name<T>();
constexpr auto bit = detail::num_name<8 * sizeof(T)>();
return detail::concat(prefix, bit);
}
else {
//static_assert("not support");
return TStr{ "unknown" };
}
}
}