I have a void pointer that I casted to a char*. I'm trying to put different data types in that char* without having to cast so much. This includes doubles, floats, int's, etc..

char* Data = static_cast<char*>(GivenPtr);

switch(reinterpret_cast<int>(Data)[0]) //Or should it be reinterpret_cast<int>(Data[0])
{
    case OBJECT:  //defined as 301;
    {
        Data[0] = 863;  //Overflow?
        Data[1] = 970;

        //OR should I be doing:

        int* pData = reinterpret_cast<int*>(Data);
        pData[0] = 863;
        pData[1] = 970;

        double* pDub = reinterpret_cast<double*>(pData[2???]);   //Index 2???
        pDub[0] = 57.99;
    }
    break;
}

Write my char* to a buffer and read it back exactly the same way it was written to:

case OBJECT2:
{
    int X = reinterpret_cast<int>(Data[1]);  //Or reinterpret_cast(Data)[1]?
    std::cout<<X;

    double pDub = reinterpret_cast<double>(Data[??]);   //?????
    std::cout<<pDub;
}
break;

How can I tell what Indicies to write to after each cast? I really don't want to cast so much. Is there a way to just write it straight to a char* and then read straight from that char? Better yet, can I do this with a void?

What about using a function templates like these ones:

template <typename T>
T read_value(char*& ptr) {
  T result = *(reinterpret_cast<T*>(ptr));
  ptr += sizeof(T);
  return result;
};

template <typename T>
void write_value(char*& ptr, const T& val) {
  *(reinterpret_cast<T*>(ptr)) = val;
  ptr += sizeof(T);
};

And then do this:

char* Data = static_cast<char*>(GivenPtr);

char* cur_ptr = Data;

switch( read_value<int>(cur_ptr) ) {
  case OBJECT:
  {
    // ... 
    double some_value = read_value<double>(cur_ptr);
    //... etc..
  };
  break;
  case OBJECT2:
    // ...
};

How can I tell what Indicies to write to after each cast?

Whenever you read/write something from the buffer, increment the pointer by the size of the value you read/wrote. This is easiest with a function template as I showed above.

Is there a way to just write it straight to a char* and then read straight from that char?

That's pretty much what you are doing already. The type casts will not really cause any overhead, beyond that of breaking word-alignment.

Better yet, can I do this with a void?

It is preferrable to do it with a char* because it has a guaranteed size of 1 byte, while a void has undefined size, which is going to cause trouble when doing the pointer incrementing.

Edited 4 Years Ago by mike_2000_17: addition

Comments
Ahh :o I never thought about templating it :o Best solution!

Hey I have a question about your method.

Can you explain to me why:

char* Data = static_cast<char*>(GivenPtr);

char* pData = Data;


write_value(pData, 765);
write_value(pData, 553);

std::cout<<read_value<int>(Data) << ", "<< read_value<int>(Data)<<std::endl;

Reads backwards? For example, it prints 553 then 765 instead of the other way around. What is the logic behind why that happens?

But if I do:

char* Data = static_cast<char*>(GivenPtr);
char* pData = Data;

write_value(pData, 765);
pData += sizeof(int);
write_value(pData, 553);

std::cout<<read_value<int>(Data) <<std::endl;
Data += sizeof(int);
std::cout<<read_value<int>(Data)<<std::endl;

It prints the other way around.. 765 then 553.

EDIT: Seems to be Order of Operations/Evaluation..

Edited 4 Years Ago by triumphost

This question has already been answered. Start a new discussion instead.