102 lines
2.6 KiB
C++
102 lines
2.6 KiB
C++
#include "name.h"
|
|
namespace refl {
|
|
namespace detail {
|
|
template<typename T>
|
|
constexpr std::string_view func_signature() noexcept {
|
|
# if defined(__clang__)
|
|
auto sign = std::string_view{ __PRETTY_FUNCTION__ };
|
|
return sign.substr(47, sign.size() - 47);
|
|
# elif defined(__GNUC__)
|
|
auto sign = std::string_view{ __PRETTY_FUNCTION__ };
|
|
return sign.substr(62, sign.size() - 62);
|
|
# elif defined(_MSC_VER)
|
|
auto sign = std::string_view{ __FUNCSIG__ };
|
|
return sign.substr(48, sign.size() - 48);
|
|
# endif
|
|
}
|
|
template<typename T>
|
|
constexpr auto raw_type_name() noexcept {
|
|
constexpr std::string_view sign = func_signature<T>();
|
|
constexpr size_t size = sign.size();
|
|
return TStr<size>{ sign };
|
|
}
|
|
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 {
|
|
return detail::raw_type_name<T>();
|
|
}
|
|
}
|
|
} |