Consider the following struct:
struct Particle
{
float scale;
float opacity;
float rotation;
};
I want the following to compile:
static_assert(indexOf<&Particle::scale>() == 0);
static_assert(indexOf<&Particle::opacity>() == 1);
static_assert(indexOf<&Particle::rotation>() == 2);
I have managed to implement a working version using Boost.PFR:
template <auto PM>
consteval int indexOf()
{
using ClassType = typename PMTraits<decltype(PM)>::ClassType;
constexpr ClassType obj{};
std::size_t result = -1;
[&]<auto... Is>(std::index_sequence<Is...>)
{
(...,
(
( static_cast<const void*>(&(boost::pfr::get<Is>(obj)))
== static_cast<const void*>(&(obj.*PM)) )
? (result = Is) : 0
)
);
}(std::make_index_sequence<boost::pfr::tuple_size_v<ClassType>>{});
return result;
}
But I am displeased by the fact that I need to create an object of type ClassType in order to make obj.*PM work.
Is there a better way of doing this that (1) does not require the creation of an object at compile-time and/or (2) is more efficient to compile?
nullptris UB, which is not allowed during constant evaluation.