Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

name_of member #259

Merged
merged 4 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++20")
add_compile_options(/utf-8)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/bigobj>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/Zc:__cplusplus>")
else()

if(NOT LINKLIBC++)
Expand Down
10 changes: 9 additions & 1 deletion iguana/detail/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include "iguana/define.h"


namespace iguana {

template <class T>
Expand Down Expand Up @@ -68,6 +67,15 @@ template <typename T, typename... Us>
struct has_type<T, std::tuple<Us...>>
: std::disjunction<std::is_same<T, Us>...> {};

template <class T>
struct member_tratis {};

template <class T, class Owner>
struct member_tratis<T Owner::*> {
using owner_type = Owner;
using value_type = T;
};

template <typename T>
inline constexpr bool is_int64_v =
std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t>;
Expand Down
89 changes: 89 additions & 0 deletions iguana/reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,95 @@ constexpr const std::string_view get_name() {
return M::name();
}

namespace detail {
#if __cplusplus < 201703L
template <auto ptr, auto ele>
constexpr bool get_index_imple() {
if constexpr (std::is_same_v<
typename member_tratis<decltype(ptr)>::value_type,
typename member_tratis<decltype(ele)>::value_type>) {
if constexpr (ele == ptr) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}

#define member_index(ptr, tp) \
[&]<size_t... I>(std::index_sequence<I...>) { \
bool r = false; \
size_t index = 0; \
((void)(!r && (r = detail::get_index_imple<ptr, std::get<I>(tp)>(), \
!r ? index++ : index, true)), \
...); \
return index; \
} \
(std::make_index_sequence<std::tuple_size_v<decltype(tp)>>{});
#else
template <typename T, typename U>
constexpr bool get_index_imple(T ptr, U ele) {
if constexpr (std::is_same_v<
typename iguana::member_tratis<decltype(ptr)>::value_type,
typename iguana::member_tratis<
decltype(ele)>::value_type>) {
if (ele == ptr) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}

template <typename T, typename Tuple, size_t... I>
constexpr size_t member_index_impl(T ptr, Tuple &tp,
std::index_sequence<I...>) {
bool r = false;
size_t index = 0;
((void)(!r && (r = get_index_imple(ptr, std::get<I>(tp)),
!r ? index++ : index, true)),
...);
return index;
}

template <typename T, typename Tuple>
constexpr size_t member_index(T ptr, Tuple &tp) {
return member_index_impl(
ptr, tp,
std::make_index_sequence<
std::tuple_size_v<std::decay_t<decltype(tp)>>>{});
}
#endif
} // namespace detail

template <auto member>
constexpr size_t index_of() {
using namespace detail;
using T = typename member_tratis<decltype(member)>::owner_type;
using M = Reflect_members<T>;
constexpr auto tp = M::apply_impl();
constexpr size_t Size = std::tuple_size_v<decltype(tp)>;
constexpr size_t index = member_index(member, tp);
static_assert(index < Size, "out of range");
return index;
}

template <auto member>
constexpr auto name_of() {
using T = typename member_tratis<decltype(member)>::owner_type;
using M = Reflect_members<T>;
constexpr auto s = M::arr()[index_of<member>()];
return std::string_view(s.data(), s.size());
}

template <typename T>
constexpr const std::string_view get_fields() {
using M = Reflect_members<T>;
Expand Down
18 changes: 18 additions & 0 deletions test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,24 @@ TEST_CASE("parse some other char") {
CHECK(p.name == "tom");
}

TEST_CASE("index_of name_of") {
constexpr size_t idx1 = iguana::index_of<&point_t::y>();
static_assert(idx1 == 1);
constexpr size_t idx2 = iguana::index_of<&person::name>();
static_assert(idx2 == 0);

CHECK(idx1 == 1);
CHECK(idx2 == 0);

constexpr auto s1 = iguana::name_of<&point_t::y>();
static_assert(s1 == "y");
constexpr auto s2 = iguana::name_of<&person::name>();
static_assert(s2 == "name");

CHECK(s1 == "y");
CHECK(s2 == "name");
}

TEST_CASE("check some types") {
using value_type = std::variant<int point_t::*, double point_t::*>;
constexpr auto map = iguana::get_iguana_struct_map<point_t>();
Expand Down
Loading