Copy allocator instead of moving it.

Since the allocator may still be used by the source of the move operation,
it cannot be moved (since that would break operations on the source).
Hence it needs to be copied.
Split data portion of typed message queue.

This change makes it easier to implement different types of message queues
without requiring large code duplication.