get alias name by adl (#773)

This commit is contained in:
qicosmos 2024-09-13 16:13:17 +08:00 committed by GitHub
parent b4eb280442
commit b8a6060176
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 35 deletions

View File

@ -28,7 +28,9 @@ concept expected = requires(Type e) {
e.has_value();
e.error();
requires std::is_same_v<void, typename remove_cvref_t<Type>::value_type> ||
requires(Type e) { e.value(); };
requires(Type e) {
e.value();
};
};
#else
template <typename T, typename = void>
@ -72,8 +74,9 @@ constexpr bool optional = !expected<T> && optional_impl<T>::value;
namespace internal {
#if __cpp_concepts >= 201907L
template <typename Type>
concept tuple_size =
requires(Type tuple) { std::tuple_size<remove_cvref_t<Type>>::value; };
concept tuple_size = requires(Type tuple) {
std::tuple_size<remove_cvref_t<Type>>::value;
};
#else
template <typename T, typename = void>
struct tuple_size_impl : std::false_type {};

View File

@ -7,9 +7,6 @@
namespace ylt::reflection {
template <typename T>
struct ylt_alias_struct;
template <typename T>
inline constexpr auto get_alias_field_names();
@ -63,29 +60,51 @@ struct member_tratis<T Owner::*> {
using value_type = T;
};
template <typename T, typename = void>
struct has_alias_struct_name_t : std::false_type {};
template <typename T>
struct has_alias_struct_name_t<
T, std::void_t<decltype(get_alias_struct_name((T*)nullptr))>>
: std::true_type {};
template <typename T, typename = void>
struct has_inner_alias_struct_name_t : std::false_type {};
template <typename T>
struct has_inner_alias_struct_name_t<
T, std::void_t<decltype(T::get_alias_struct_name((T*)nullptr))>>
: std::true_type {};
template <typename T>
constexpr bool has_alias_struct_name_v = has_alias_struct_name_t<T>::value;
template <typename T>
constexpr bool has_inner_alias_struct_name_v =
has_inner_alias_struct_name_t<T>::value;
template <typename T, typename = void>
struct has_alias_field_names_t : std::false_type {};
template <typename T>
struct has_alias_field_names_t<
T, std::void_t<decltype(ylt_alias_struct<T>::get_alias_field_names())>>
T, std::void_t<decltype(get_alias_field_names((T*)nullptr))>>
: std::true_type {};
template <typename T>
inline constexpr bool has_alias_field_names_v =
has_alias_field_names_t<T>::value;
template <typename T, typename = void>
struct has_alias_struct_names_t : std::false_type {};
struct has_inner_alias_field_names_t : std::false_type {};
template <typename T>
struct has_alias_struct_names_t<
T, std::void_t<decltype(ylt_alias_struct<T>::get_alias_struct_name())>>
struct has_inner_alias_field_names_t<
T, std::void_t<decltype(T::get_alias_field_names((T*)nullptr))>>
: std::true_type {};
template <typename T>
inline constexpr bool has_alias_struct_name_v =
has_alias_struct_names_t<T>::value;
constexpr bool has_alias_field_names_v = has_alias_field_names_t<T>::value;
template <typename T>
constexpr bool has_inner_alias_field_names_v =
has_inner_alias_field_names_t<T>::value;
template <typename T, typename U, size_t... Is>
inline constexpr void init_arr_with_tuple(U& arr, std::index_sequence<Is...>) {
@ -217,7 +236,10 @@ struct field_alias_t {
template <typename T>
inline constexpr auto get_alias_field_names() {
if constexpr (internal::has_alias_field_names_v<T>) {
return ylt_alias_struct<T>::get_alias_field_names();
return get_alias_field_names((T*)nullptr);
}
else if constexpr (internal::has_inner_alias_field_names_v<T>) {
return T::get_alias_field_names((T*)nullptr);
}
else {
return std::array<std::string_view, 0>{};
@ -227,7 +249,10 @@ inline constexpr auto get_alias_field_names() {
template <typename T>
constexpr std::string_view get_struct_name() {
if constexpr (internal::has_alias_struct_name_v<T>) {
return ylt_alias_struct<T>::get_alias_struct_name();
return get_alias_struct_name((T*)nullptr);
}
else if constexpr (internal::has_inner_alias_struct_name_v<T>) {
return T::get_alias_struct_name((T*)nullptr);
}
else {
return type_string<T>();
@ -239,7 +264,8 @@ inline constexpr std::array<std::string_view, members_count_v<T>>
get_member_names() {
auto arr = internal::get_member_names<T>();
using U = ylt::reflection::remove_cvref_t<T>;
if constexpr (internal::has_alias_field_names_v<U>) {
if constexpr (internal::has_alias_field_names_v<U> ||
internal::has_inner_alias_field_names_v<U>) {
constexpr auto alias_arr = get_alias_field_names<U>();
for (size_t i = 0; i < alias_arr.size(); i++) {
arr[alias_arr[i].index] = alias_arr[i].alias_name;

View File

@ -291,14 +291,13 @@ struct next_obj_t {
};
YLT_REFL(next_obj_t, x, y);
template <>
struct ylt::reflection::ylt_alias_struct<next_obj_t> {
static constexpr std::string_view get_alias_struct_name() { return "next"; }
static constexpr auto get_alias_field_names() {
return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}};
}
};
constexpr std::string_view get_alias_struct_name(next_obj_t *) {
return "next";
}
constexpr auto get_alias_field_names(next_obj_t *) {
using namespace ylt::reflection;
return std::array{field_alias_t{"w", 0}, field_alias_t{"h", 1}};
}
struct out_object {
std::unique_ptr<int> id;
@ -307,14 +306,11 @@ struct out_object {
};
YLT_REFL(out_object, id, name, obj);
template <>
struct ylt::reflection::ylt_alias_struct<out_object> {
static constexpr std::string_view get_alias_struct_name() { return "qi"; }
static constexpr auto get_alias_field_names() {
return std::array{field_alias_t{"i", 0}, field_alias_t{"na", 1}};
}
};
constexpr std::string_view get_alias_struct_name(out_object *) { return "qi"; }
constexpr auto get_alias_field_names(out_object *) {
using namespace ylt::reflection;
return std::array{field_alias_t{"i", 0}, field_alias_t{"na", 1}};
}
void test_alias() {
out_object m{std::make_unique<int>(20), "tom", {21, 42}};