I would like to increase the size of a data type once that data type's limit has been reached. For example, let's say I have a class:
struct Counter {
unsigned short x;
void IncrementCount() { x++; }
};
Once I change the value of Counter.x, I would like it to promote x to be an unsigned int instead of an unsigned short.
int main() {
Counter c;
c.x = ~0; // c.x is max unsigned short value 2^16
c.IncrementCount(); // c.x is now an unsigned int with value 2^16 + 1, NOT an unsigned short with value 0
}
The reason for me doing this is so that I store as little memory in my Counter class as possible.
Obviously I want as little impact to performance and readability as possible.
I've considered using a void pointer and casting to the appropriate data type (but how would I track the type without using extra memory?), changing the IncrementCount() method on my Counter class and creating a new Counter object (with an int instead of a short) when the unsigned short's limit is reached (but this will add some complexity, as well as an extra if on every increment). Maybe a bitmap which increases in size every time it needs an extra bit? Still adds complexity and some performance hit.
If I have 10 million Counters, I don't want to use an extra 2 bytes for an int (as that would require 20 million extra bytes). I know alignment might fix the issue for short -> int but I want this to also be valid for int32 -> int64 and other types. It is also worth noting that this is a runtime problem (I don't know the size at compile time).
Is there a simpler way in C++ to do this?