
Christopher Kohlhoff wrote:
It lets me define my message structures once to cater for all types of endianness. E.g. a very simple example:
tempalte <endianness E> struct message { endian<E, short, 2> first; endian<E, int, 4> second; endian<E, int, 4> third; ... };
Sender may write:
message<native> m; m.first = ... write(sock, buffer(&m, sizeof(m)));
Receiver may write:
if (peer_is_big_endian) { message<big> m; read(sock, buffer(&m, sizeof(m))); process_message(m); } else { message<little> m; read(sock, buffer(&m, sizeof(m))); process_message(m); }
And both sender and receiver may make use of template functions for processing message structures:
template <endianness E> void process_message(message<E>& m) { ... }
According to your example, the process_message function seems to be used only by the receiver, and this is actually logical, so I can't see the benefit of 'native' there. On the other hand, the definition of struct message, can benefit from it, I agree. So to provide a solution for the struct, I suggest to add a 'type selector' to the suggestion I described (too many times) in this thread. This selector would be defined as follows: template <endianness E, typename T> struct endian_selector { typedef ... type; } where: endian_selector<big , T>::type is big_endian<T> endian_selector<little, T>::type is little_endian<T> endian_selector<native, T>::type is T Yes, there is a 'native' option in here, you convinced me. I think this allows the struct message to be defined elegantly as in your example.