A while back I was having some issues regarding sending enums through sf::Packet. The primary solution was to cast the enum to an int, send it, then do more casting on the receiving end. The resulting code looked something like this:
enum class MyEnum
{
VALUE1,
VALUE2
}
...
// Sending
sf::Packet oPacket;
oPacket << static_cast<std::uint8_t>(MyEnum::VALUE1);
...
// Receiving
std::uint8 ui8Value;
sf::Packet oReceived;
// receive the packet
oReceived >> ui8Value;
MyEnum eMyEnume = static_cast<MyEnum>(ui8Value);
This is quite messy and verbose and its horrible to maintain, especially if MyEnum grew to include values which exceeded values of 255.
The simple option would be to cast everything to either int32 or in64 (And their unsigned counter-parts), but thats boring (And casting is ugly).
So I wrote some sf::Packet<</>> overloads to allow sending enums through sf::Packet with the help of templates and C++11 underlying types for enumerations and type traits:
template<typename T>
inline typename std::enable_if<std::is_enum<T>::value, sf::Packet&>::type
operator<<(sf::Packet& roPacket, const T& rkeMsgType)
{
return roPacket << static_cast<std::underlying_type<T>::type>(rkeMsgType);
}
template<typename T>
inline typename std::enable_if<std::is_enum<T>::value, sf::Packet&>::type
operator>>(sf::Packet& roPacket, T& reMsgType)
{
std::underlying_type<T>::type xMsgType;
roPacket >> xMsgType;
reMsgType = static_cast<T>(xMsgType);
return roPacket;
}
The code is probably a bit overkill, but it handles the correct casting for implicit enum types (signed int) explicit types.
The resulting send/receive code would look like this:
// Sending
sf::Packet oPacket;
oPacket << MyEnum::VALUE1;
...
// Receiving
MyEnum eMyEnume;
sf::Packet oReceived;
// receive the packet
oReceived >> eMyEnume;
The code has been tested and works as far as I have tested it.