In my simulation engine, I have a SimulationObject template that I specialize for different type of SimulationObjects using a Tag. I also have a SimulationObjects type that lists all the SimulationObjects that I support.
struct Particle3D{};
struct RigidBody{};
template <typename Tag>
struct SimulationObject{};
struct SimulationObjects {
using value = std::tuple<SimulationObject<Particle3D>, SimulationObject<RigidBody>>;
}
I also have a bunch of Projection classes which implement a common interface. Each SimulationObject<> particular type only supports a set of those Projections, so I list them using a Projections<> template. Each SimulationObject can only hold 0 or 1 of those Projections, so I use a variant for that.
struct Projection3D{};
struct AnotherProjection3D{};
struct ProjectionRB{};
…
template <>
struct Projections<RigidBody>
{
using value = std::variant<std::monostate, ProjectionRB>;
}
Since I can have several SimulationObject<> of each type, and each one can have a projection. I want to have a tuple where I store the active projections.
struct SystemMatrix
{
template <typename Tag>
struct ProjectionBlock
{
int offset;
std::reference_wrapper<const typename Projections<Tag>::value> projection;
};
// How to write this using the SimulationObject info? I have all the possible SimulationObject types listed there
std::tuple<
std::vector<ProjectionBlock<const Projections<Particle3D>>>,
std::vector<ProjectionBlock<const Projections<RigidBody>>>> projections;
}
Is there a way to create the SystemMatrix::projections such that I don't need to list all the supported SimulationObjects types?
structto provide proper names for each field, so code it easier to read code and maintain.SystemMatrix::projectionsshould be created? You didn't explain this. You just wrote that this type shouldn't be created manually. You need some other type which binds all interesting types together, so template could transform this type to desired tuple.