
Integer types in C and C++ are a mess. For example, I have made a library
where a task is identified by a unique unsigned integer. The extra information
about the tasks is stored in a std::vector. When a new task is created, I use
the size() method to get the next id, I assign it to the task and then
push_back the (pointer to) task structure into the vector. Now, the task
structure has also an "unsigned int id" field. In 64-bit mode,
sizeof(unsigned) == 4, sizeof(std::vector::size_type) == 8
I get a warnings about type truncation, and obviously, I don't like them. But
I like explicit casts and turning off warnings even less. No, I don't want to
tie together size_type and task id type (unsigned int). One reason is
"aesthetic", another reason is that I don't want the task id type to be larger
than necessary (heck, even a 16-bit type would have been enough), because the
task IDs will be copied verbatim into another std::vector<unsigned> for further
processing (edge lists of a graph). Doubling the size of an integer type shall
have bad effects on CPU caches, and I don't want to do it.
What to do? Encapsulate into "get_next_id()" function? Have a custom size()
function/macro that just casts the result of vector::size and returns it?
==
Another example: an external library defines its interfaces with signed integer
types, I work with unsigned types (why? to avoid even more warnings when
comparing task IDs with vector::size() result, as in assert(task->id <
tasks.size()), which are abundant in my code). Again, some warnings are
unavoidable.
What to do to have "clean" code?
==
Does anyone know about an integer class that lets the user define the number of
bits used for storage, lower allowed bound and upper allowed bound for the
range? Like: template