What I actually need is portable compare and print for *nix pthread identifiers (pthread_t). pthread_equal function exists to compare two thread id's for equality, however it's not possible to compare them with operators < <= >= > (portable I mean of course) because on some of implementations pthread_t is a pointer to structure. So I found solution which I would like to share and discuss it's portability.
Suppose we have thred_id class wrapper, which should be less-then-comparable, equality-comparable and of course printable. I'm making template class with two partial specialization - one for pointers and one for arithmetic types
template <typename T, bool A = is_arithmetic<T>::value>
struct hash
{
static unsigned long calculate(T thread_id)
{
return hash<T*, A>::calculate(&thread_id);
}
};
template <typename T>
struct hash<T*, false>
{
static unsigned long calculate(T* thread_id)
{
std::size_t hash = 0;
if (char* data = reinterpret_cast<char*>(thread_id))
{
for (int i = 0; i < sizeof(T); ++i)
{
hash = (hash << 6) ^ (hash >> 26) ^ data[i];
}
}
return hash;
}
};
template <typename T>
struct hash<T, true>
{
static unsigned long calculate(T thread_id)
{
return static_cast<unsigned long>(thread_id);
}
};
So how does it work. If we need to compare two thread ids we just simply call
pthread_equal(tid1, tid2);
but for operator < we use hash to compare
hash<pthread_t>::calculate(tid1) < hash<pthread_t>::calculate(tid2)
So here
if pthread_t
is implemented as a pointer then we will calculate hash for the pointed object.
If it is arithmetic type then we will just try to cast it to unsigned int.
If it is implemented as a structure - we will calculate hash for the structure object itself.
Hash value is going to be used only for operator less and thread id output.
What do you think of it? How portable is this solution and is there anything better then that?
Thanks everybody in advance.