Skip to content

Commit d046c13

Browse files
Merge pull request #17 from contour-terminal/improvement/CountMembers
Rework CountMembers<T>
2 parents 6fdb93f + 72723a0 commit d046c13

File tree

1 file changed

+15
-35
lines changed

1 file changed

+15
-35
lines changed

include/reflection-cpp/reflection.hpp

Lines changed: 15 additions & 35 deletions
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,22 @@ namespace detail
142121
// return std::source_location::current().function_name();
143122
return REFLECTION_PRETTY_FUNCTION;
144123
}
124+
125+
template <class AggregateType, class... Args>
126+
requires(std::is_aggregate_v<AggregateType>)
127+
constexpr inline auto CountMembers = []() constexpr {
128+
if constexpr (requires { AggregateType { Args {}..., AnyType {} }; })
129+
return CountMembers<AggregateType, Args..., AnyType>;
130+
else
131+
return sizeof...(Args);
132+
}();
133+
145134
} // namespace detail
146135

147-
template <class T, class... Args>
136+
// Count the number of members in an aggregate type.
137+
template <class T>
148138
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-
}();
139+
constexpr inline auto CountMembers = detail::CountMembers<std::remove_cvref_t<T>>;
160140

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

0 commit comments

Comments
 (0)