Skip to content

Commit

Permalink
get alias name by adl
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos committed Sep 13, 2024
1 parent b4eb280 commit 3203277
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 35 deletions.
9 changes: 6 additions & 3 deletions include/ylt/reflection/member_count.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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 {};
Expand Down
58 changes: 42 additions & 16 deletions include/ylt/reflection/member_names.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@

namespace ylt::reflection {

template <typename T>
struct ylt_alias_struct;

template <typename T>
inline constexpr auto get_alias_field_names();

Expand Down Expand Up @@ -64,28 +61,50 @@ struct member_tratis<T Owner::*> {
};

template <typename T, typename = void>
struct has_alias_field_names_t : std::false_type {};
struct has_alias_struct_name_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())>>
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>
inline constexpr bool has_alias_field_names_v =
has_alias_field_names_t<T>::value;
constexpr bool has_inner_alias_struct_name_v =
has_inner_alias_struct_name_t<T>::value;

template <typename T, typename = void>
struct has_alias_struct_names_t : std::false_type {};
struct has_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_alias_field_names_t<
T, std::void_t<decltype(get_alias_field_names((T*)nullptr))>>
: std::true_type {};

template <typename T, typename = void>
struct has_inner_alias_field_names_t : std::false_type {};

template <typename T>
inline constexpr bool has_alias_struct_name_v =
has_alias_struct_names_t<T>::value;
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>
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...>) {
Expand Down Expand Up @@ -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>{};
Expand All @@ -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>();
Expand All @@ -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;
Expand Down
28 changes: 12 additions & 16 deletions src/struct_xml/examples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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}};
Expand Down

0 comments on commit 3203277

Please sign in to comment.