I recently have hit a wall, and can’t seem to find an elegant solution to my problem:
I have different data structures of different number of elements, all of which are aligned to pointer-size and are not larger than a pointer, ex.:
struct DATA_0{
size_t Value;
size_t *PtrValue;
bool BoolValue;
};
or
struct DATA_1{
size_t Value0;
size_t Value1;
size_t *PtrValue;
void *PtrBuffer;
bool BoolValue;
const char *StringBuffer;
}
The input comes in a form like this:
struct INPUT{
size_t *DataBuffer;
size_t DataVector[16];
};
I need to map the data structures to different elements from either the DataBuffer or the DataVector, at compile time:
- the mapping rule is being controlled by #defines/compile time switches – for a given compilation configuration, the mapping rule is the same for all structures.
- a given data structure member can be mapped to either a DataBuffer or a DataVector
- a data structure member’s index (no need for offset, since the data is aligned) defines the element it is mapped to, ex.: in some cases the element at index 0 (DATA_0::Value or DATA_1::Value0 for example) maps to DataVector[3], and in other cases to DataBuffer[0]
- for those elements, that have no index based mapping rules (usually the first 2-4 elements from a structure have such rule), they all should map to sequential elements, onward from a given element from DataBuffer
Some example of desired usage:
INPUT_DATA *input;
data_mapping<DATA_0> mapping_0(input);
//will fetch data from input->DataVector[0] in some cases, input->DataBuffer[0] in other
size_t tmpValue = mapping_0[Value];
data_mapping<DATA_1> mapping_1(input);
//will fetch data from input->DataVector[1] in some cases, input->DataBuffer[3] in other
size_t tmpPtrBuffer = mapping_1[PtrBuffer];
NOTE: the data does not need to be necessarily represented by structures, it can be even variadic template argument too, ex.: <size_t, Value, size_t, PtrValue, bool, BoolValue>
Here is an pseudo-code example of what i am trying to achieve:
template<class TMember, class TData>
TMember GetElement(INPUT_DATA *Input, TData Data)
{
#ifdef FIRST_CASE
if(indexof(TMember) == 0)
{
return Input->DataVector[0];
}
if(indexof(TMember) == 1)
{
return Input->DataVector[1];
}
return Input->DataBuffer[indexof(TMember) - 2];
#else
if(indexof(TMember) == 0)
{
return Input->DataVector[2];
}
if(indexof(TMember) == 1)
{
return Input->DataVector[3];
}
if(indexof(TMember) == 2)
{
return Input->DataVector[4];
}
if(indexof(TMember) == 3)
{
return Input->DataVector[5];
}
return Input->DataBuffer[indexof(TMember)];
#endif
}
size_t tmpValue = GetElement<Value>(input,DATA_0);
size_t tmpPtrBuffer = GetElement<PtrBuffer>(input,DATA_1);