150 lines
3.4 KiB
C++
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
|