engine/dep/include/ctti/nameof.hpp
2024-12-02 18:48:18 -06:00

150 lines
3.4 KiB
C++

#ifndef CTTI_NAMEOF_HPP
#define CTTI_NAMEOF_HPP
#include <ctti/detail/pretty_function.hpp>
#include <ctti/detail/name_filters.hpp>
#include <ctti/detail/meta.hpp>
#include <ctti/detail/language_features.hpp>
#include <ctti/type_tag.hpp>
#include <ctti/static_value.hpp>
#include <type_traits>
#include <cstdint>
namespace ctti
{
template<typename T>
constexpr ctti::detail::cstring nameof();
template<typename T, T Value>
constexpr ctti::detail::cstring nameof();
namespace detail
{
template<typename T, typename = void>
struct TypeNameLength :
std::integral_constant<
std::size_t,
ctti::nameof<T>().length()
>
{};
template<typename R, typename Class>
struct TypeNameLength<R Class::*, void> :
std::integral_constant<
std::size_t,
ctti::nameof<R Class::*>().length()
>
{};
template<typename Enum>
struct TypeNameLength<Enum, typename std::enable_if<std::is_enum<Enum>::value>::type> :
std::integral_constant<
std::size_t,
ctti::nameof<Enum>().length()
>
{};
}
template<typename T, T Value>
constexpr ctti::detail::cstring nameof();
namespace detail
{
template<typename T>
struct another_level_of_indirection {};
template<typename T, typename = void>
struct nameof_impl
{
static constexpr ctti::detail::cstring apply()
{
return ctti::detail::filter_typename_prefix(ctti::pretty_function::type<T>().pad(
CTTI_TYPE_PRETTY_FUNCTION_LEFT,
CTTI_TYPE_PRETTY_FUNCTION_RIGHT
));
}
};
template<typename T>
struct nameof_impl<T, ctti::meta::void_t<decltype(T::ctti_nameof())>>
{
static constexpr ctti::detail::cstring apply()
{
return T::ctti_nameof();
}
};
template<typename T, T Value>
struct nameof_impl<another_level_of_indirection<ctti::static_value<T, Value>>, void>
{
static constexpr ctti::detail::cstring apply()
{
return ctti::pretty_function::value<T, Value>().pad(
CTTI_VALUE_PRETTY_FUNCTION_LEFT + ctti::detail::TypeNameLength<T>::value + CTTI_VALUE_PRETTY_FUNCTION_SEPARATION,
CTTI_VALUE_PRETTY_FUNCTION_RIGHT
);
}
};
template<typename T, T Value>
struct nameof_impl<ctti::static_value<T, Value>, void>
{
static constexpr ctti::detail::cstring apply()
{
return ctti::nameof<T, Value>();
}
};
}
template<typename T>
constexpr ctti::detail::cstring ctti_nameof(ctti::type_tag<T>)
{
return ctti::detail::nameof_impl<T>::apply();
}
template<typename T, T Value>
constexpr ctti::detail::cstring ctti_nameof(ctti::static_value<T, Value>)
{
return ctti::detail::nameof_impl<ctti::detail::another_level_of_indirection<ctti::static_value<T, Value>>>::apply();
}
template<typename T>
constexpr ctti::detail::cstring nameof()
{
using namespace ctti;
return ctti_nameof(ctti::type_tag<T>());
}
template<typename T, T Value>
constexpr ctti::detail::cstring nameof()
{
using namespace ctti;
return ctti_nameof(ctti::static_value<T, Value>());
}
#ifdef CTTI_HAS_VARIABLE_TEMPLATES
template<typename T>
constexpr ctti::detail::cstring nameof_v = ctti::nameof<T>();
// CONSIDER USING nameof_v<CTTI_STATIC_VALUE(value)> INSTEAD
template<typename T, T Value>
constexpr ctti::detail::cstring nameof_value_v = ctti::nameof<T, Value>();
#endif // CTTI_HAS_VARIABLE_TEMPLATES
}
namespace std
{
constexpr ctti::detail::cstring ctti_nameof(ctti::type_tag<std::string>)
{
return "std::string";
}
}
#endif // CTTI_NAMEOF_HPP