I have an file handler, that reads and writes custom binary files. To save myself work I've inherited multiple data from one base struct (base_p
):
struct base_p{
protected:
uint32_t v0= 0;
uint32_t v1= 0;
uint32_t v2= 0;
friend struct f_block;
// other friends
};
Now during building of my internal blocks of that file, I've inherited that struct into multiple non POD type:
struct f_block:public base_p{
f_block(){
this->v0 = 0x3f580058; // an magic number of the block
this->v1 = 0x1000004D; // version and use type
this->v2 = 0;
}
f_block(uint32_t data){
this->v0 = 0x3f580058; // an magic number of the block
this->v1 = 0x1000004D; // version and usage type
this->v2 = data;
}
operator uint8_t(){ return this->v1 & 0xff; }
operator bool(){return this->v2 != 0 ;}
friend std::ostream& operator<<( std::ostream& os, f_block& fb );
};
std::ostream& operator<<( std::ostream& os, f_block& fb ){
union {
uint32_t vrt;
unsigned char parts[4];
}temp;
temp. vrt = fb. v2;
return os << temp. parts[3] << temp. parts[2] << temp. parts[1] << temp. parts[0];
}
Inside my file handler, I have use for both structures. For example if I need to pass data somewhere, I need to extract data as base_p
. But my block definition has an extra feature that usage
serves and compression key and within data
(v2) I have also stored some information such as bit offset from the end, length of featured blocks . . . and many others. So extracting function would look something along of lines:
struct file_handler{
std::vector<base_p> data;
file_handler():data(0){}
virtual bool read(const char *filename) = 0; // to be overridden
virtual bool write(const char *filename)= 0; // to be overridden
virtual bool set( base_p &data){
// if data is base_p , push_back data as normal POD
// if data is f_block, push_back data as deflated version
// don't store anything in vector if none
}
virtual bool get( base_p &data){
// if data is base_p, returns lasts 3 elements v2(data) fields
// if data is f_block, returns last element as f_block - inflated,
// set data as 0 if none
}
}
I've tried to catch an error of calling a function that doesn't exist in base_p
, but it doesn't suit me since I am building multiple file handlers upon file_handler
struct that should accept other data types. I am secure enough to start building other file types once I can successfully implement file_handler
. What I need is something along of data type switch statement.
Since I come from python
background, in it I could do something along of lines isinstance
or something similar. But this is C++ so there isn't such implementation - that I am aware of.
I have searched and I've found some elements that seem to have potential to solve my problem, but most of them are for outdated versions or too abstract to wrap my head around to generate an logic solution.
- SFINAE and void : mentions some sort of concept that SFINAEs follow, and compound concepts which is too abstract in question for me to successfully make valid implementation.
- HasMember SFINAE : which seems feasible for constructor recognition, but best answer is written in
c++03
with no mention if it translates toc++11
aka version I am currently using.
Is there a way to distinguish between PODs and non-PODs ?