mardi 20 juillet 2021

Group classes that are based on a template?

I don't want to shoot myself in the foot, so I will provide a little context in case this is an XY problem and there is a better way to deal with this: I have a lot of data in a lot of binary files; these data come from various hardware so I have data in int, float, double, long double, etc.

These data have a header to identify where it comes from (which equipment), type of data (int, double, etc.) what was being done when the data was obtained (physics run, calibration, testing, etc.) and other things.

The best, and most intuitive way, to handle these data I have thought about is the following:

Have a Header class that gives the information about the data:

class Header {
    public:
        int event_id;
        int time_stamp;
        int data_size;
        int trigger_mask;
};

And then have a class template for the data (header plus a vector containing the actual data):

template<class T> class Data {
    public:
        Header data_header;
        std::vector<T> values;
};

The problem is that people might want to, depending on the analysis they want to do, group different Data<X> objects. The easiest example would be if people want to group the data (same type) collected by all the EQUIPMENT Xs.

std::vector<Data<double>> x_signals;

But what if people want to group all the data produced by EQUIPMENT X and loop through it. This is not necessarily all of the same type, the same equipment can throw some data in double for some things, and some other data in int.

Another case would be when people are reading the Data objects from the binary file. They may want to have a std::vector<Data> and push to it the data as they read it from the file. But this also wouldn't be possible.

The possible solutions I have though about are:

  1. Do nothing, and it would be the users problem how to handle these Data objects. They could have e.g
std::vector<Data<int>> int_data;
std::vector<Data<double>> double_data;
std::vector<Data<float>> float data;

And then they can push the Data they read into the correct container. If they want the Data with a specific characteristic (event_id, time_stamp, etc.) they would have to loop through all the containers above (and maybe store the indices of the data they want somewhere else).

  1. Provide a variadic template that keeps different Data types in a tuple:
template<class ...Types> class DataPack {
    public:
        std::tuple<Types...> data_pack;
};

But this would require the number of Data objects to be known before hand for a DataPack. We couldn't push Data into a DataPack as we read the file, and there is no way we can know how many Data objects we collected before we read the file.

  1. Make Data inherit from Header. This way we can have vectors of "headers" and use polymorphism. The problem is that Data is not a type of header; Data has a header. Inheritance feels weird and non-intuitive, which is a bit of a red flag.

I am a bit confused, and I don't know what the best approach would be. Am I thinking about all this in the wrong way? All three options seem to have a different degree of ugliness; I don't feel happy or confident with any of them.

Aucun commentaire:

Enregistrer un commentaire