25#include "char8_t_remediation.hpp"
26#include "meta/literal_string.hpp"
27#include "type_list.hpp"
34namespace essence::meta::detail {
35 inline constexpr std::size_t max_fields = 256;
38 consteval auto qualified_name_of_impl() noexcept {
41 constexpr std::size_t suffix_size{16};
42 constexpr std::string_view keyword{U8(
"essence::meta::detail::qualified_name_of_impl<")};
43 constexpr std::string_view signature{__FUNCSIG__};
44#elif defined(__GNUC__)
46 constexpr std::size_t suffix_size{1};
47 constexpr std::string_view keyword{U8(
"[with T = ")};
48 constexpr std::string_view signature{__PRETTY_FUNCTION__};
49#elif defined(__clang__)
51 constexpr std::size_t suffix_size{1};
52 constexpr std::string_view keyword{U8(
"[T = ")};
53 constexpr std::string_view signature{__PRETTY_FUNCTION__};
55#error "Unsupported compiler."
57 constexpr auto prefix_size = signature.find(keyword) + keyword.size();
58 constexpr auto intermediate = signature.substr(prefix_size, signature.size() - prefix_size - suffix_size);
60 return meta::literal_string{
61 std::span<
const char, intermediate.size()>{intermediate.data(), intermediate.size()}};
65namespace essence::meta {
70 template <
typename T, meta::literal_
string Name, auto FieldPtr>
71 requires std::is_member_object_pointer_v<
decltype(FieldPtr)>
75 static constexpr auto&& name = Name;
78 requires std::same_as<T, std::decay_t<U>>
79 static constexpr decltype(
auto) value_ref(U&& obj)
noexcept {
80 return (std::forward<U>(obj).*FieldPtr);
86 static constexpr auto value = detail::qualified_name_of_impl<T>();
94 static constexpr auto value = [] {
97 constexpr std::string_view qualified_name{qualified_name_of_v<T>};
98 constexpr auto template_argument_beginning_token_index = qualified_name.find_first_of(U8(
'<'));
99 constexpr auto scope_token_index = qualified_name.rfind(U8(
"::"), template_argument_beginning_token_index);
100 constexpr auto class_name_index = scope_token_index != std::string_view::npos ? scope_token_index + 2 : 0;
101 constexpr auto result = qualified_name.substr(class_name_index);
103 return meta::literal_string{std::span<
const char, result.size()>{result.data(), result.size()}};
107 template <
typename T>
110 template <
typename T>
113 using type =
typename std::decay_t<T>::es_meta_field_info_list_type;
116 template <
typename T>
117 using get_fields_t =
typename get_fields<T>::type;
119 template <
typename T, meta::literal_
string Name>
122 using type = at_if_t<get_fields_t<T>, []<
typename U>(std::type_identity<U>) {
return U::name == Name; }>;
125 template <
typename T, meta::literal_
string Name>
126 using get_field_by_name_t =
typename get_field_by_name<T, Name>::type;
129#define ES_MAKE_TERMINATOR_IMPL(suffix) using es_meta_terminator_##suffix = void
130#define ES_MAKE_TERMINATOR(suffix) ES_MAKE_TERMINATOR_IMPL(suffix)
131#define ES_META_MAKE_FIELD_INFO_NAME(name) es_meta_field_info_##name
132#define ES_META_GATHER_FIELDS decltype(es_meta_gather_fields(essence::rank<essence::meta::detail::max_fields>{}))
134#define ES_IDENTITY(...) decltype(static_cast<__VA_ARGS__ (*)()>(nullptr)())
136#define ES_BEGIN_FIELDS(type) \
137 using es_meta_this_type = type; \
138 static constexpr std::string_view es_meta_this_type_name{U8(#type)}; \
139 inline static essence::type_list<> es_meta_gather_fields(essence::rank<0>)
141#define ES_FIELD(type, name) \
143 using ES_META_MAKE_FIELD_INFO_NAME(name) = \
144 essence::meta::field_info<es_meta_this_type, U8(#name), &es_meta_this_type::name>; \
145 inline static auto es_meta_gather_fields(essence::rank<ES_META_GATHER_FIELDS::size + 1>) \
146 -> essence::append_t<ES_META_GATHER_FIELDS, ES_META_MAKE_FIELD_INFO_NAME(name)>
148#define ES_END_FIELDS using es_meta_field_info_list_type = ES_META_GATHER_FIELDS
Definition type_list.hpp:47