Skip to content

Commit c061e6c

Browse files
Rework CountMembers<T>
Signed-off-by: Christian Parpart <[email protected]>
1 parent 6fdb93f commit c061e6c

File tree

1 file changed

+16
-35
lines changed

1 file changed

+16
-35
lines changed

include/reflection-cpp/reflection.hpp

+16-35
Original file line numberDiff line numberDiff line change
@@ -101,32 +101,11 @@ inline constexpr auto JoinStringLiterals = detail::join<Strs...>();
101101

102102
namespace detail
103103
{
104-
struct any_t final
104+
// This helper-struct is only used by CountMembers to count the number of members in an aggregate type
105+
struct AnyType final
105106
{
106-
#if defined(__clang__)
107-
#pragma clang diagnostic push
108-
#pragma clang diagnostic ignored "-Weverything"
109-
template <class T>
110-
requires(!std::same_as<T, const char*> && !std::same_as<T, std::nullptr_t>)
111-
[[maybe_unused]] constexpr operator T() const;
112-
#pragma clang diagnostic pop
113-
#elif defined(_MSC_VER)
114-
template <class T>
115-
requires(!std::same_as<T, const char*> && !std::same_as<T, std::nullptr_t>)
116-
[[maybe_unused]] constexpr operator T() const;
117-
#else
118-
#pragma GCC diagnostic push
119-
#pragma GCC diagnostic ignored "-Wmissing-declarations"
120107
template <class T>
121-
requires(!std::same_as<T, const char*> && !std::same_as<T, std::nullptr_t>)
122108
[[maybe_unused]] constexpr operator T() const;
123-
#pragma GCC diagnostic pop
124-
#endif
125-
126-
[[maybe_unused]] constexpr operator std::string_view() const
127-
{
128-
return {};
129-
}
130109
};
131110

132111
template <auto Ptr>
@@ -142,21 +121,23 @@ namespace detail
142121
// return std::source_location::current().function_name();
143122
return REFLECTION_PRETTY_FUNCTION;
144123
}
124+
125+
template <class T, class... Args>
126+
requires(std::is_aggregate_v<std::remove_cvref_t<T>>)
127+
constexpr inline auto CountMembers = []() constexpr {
128+
using AggregateType = std::remove_cvref_t<T>;
129+
if constexpr (requires { AggregateType { Args {}..., AnyType {} }; })
130+
return CountMembers<AggregateType, Args..., AnyType>;
131+
else
132+
return sizeof...(Args);
133+
}();
134+
145135
} // namespace detail
146136

147-
template <class T, class... Args>
137+
// Count the number of members in an aggregate type.
138+
template <class T>
148139
requires(std::is_aggregate_v<std::remove_cvref_t<T>>)
149-
inline constexpr auto CountMembers = [] {
150-
using V = std::remove_cvref_t<T>;
151-
if constexpr (requires { V { Args {}..., detail::any_t {} }; })
152-
{
153-
return CountMembers<V, Args..., detail::any_t>;
154-
}
155-
else
156-
{
157-
return sizeof...(Args);
158-
}
159-
}();
140+
constexpr inline auto CountMembers = detail::CountMembers<T>;
160141

161142
constexpr size_t MaxReflectionMemerCount = 50; // should go as high as 256, I guess? for now 30 is enough
162143

0 commit comments

Comments
 (0)