模板化字节交换
//模板化的字节交换函数 #include <sys/types.h> #include <cstdint> #include <cstdlib> //用法:当我需要对某个值交换字节序并序列化该值的时候,我只需要调用一个函数Write即可。 //不需要关心是什么类型,不需要关心要调用哪个函数,一切都由模板帮我们实现 template <typename T> void Write(T inData) { T swappedData = ByteSwap(inData); Write(&swappedData, sizeof(swappedData)); } //一: //先实现交换字节的函数的特化版本 inline uint16_t ByteSwap2(uint16_t inData) { return (inData << 8) | (inData >> 8); } inline uint32_t ByteSwap4(uint32_t inData) { return ((inData << 24) & 0xff000000) | ((inData << 8) & 0x00ff0000) | ((inData >> 8) & 0x0000ff00) | ((inData >> 24) & 0x000000ff); } inline uint64_t ByteSwap8(uint64_t inData) { return ((inData >> 56) & 0x00000000000000ff) | ((inData >> 40) & 0x000000000000ff00) | ((inData >> 24) & 0x0000000000ff0000) | ((inData >> 8) & 0x00000000ff000000) | ((inData << 8) & 0x000000ff00000000) | ((inData << 24) & 0x0000ff0000000000) | ((inData << 40) & 0x00ff000000000000) | ((inData << 56) & 0xff00000000000000); } //二:实现特化类和相应的函数 template<typename T> class ByteSwapper<T, 2> { public: T Swap(T inData) const { uint16_t result = ByteSwap2(inData); return result; } }; template<typename T> class ByteSwapper<T, 4> { public: T Swap(T inData) const { uint32_t result = ByteSwap4(inData); return result; } }; template<typename T> class ByteSwapper<T, 8> { public: T Swap(T inData) const { uint64_t result = ByteSwap8(inData); return result; } }; //三:依据推导出来的inData数据类型调用某个特化类的函数 template <typename T> T ByteSwap(T inData) { return ByteSwapper<T, sizeof(T)>().Swap(inData); } //四:不足的地方是,以上的实现只能针对无符号整数的字节序转换 //如果想要支持float、double、有符号整数等其他数据类型的字节转换,需要增加多一个类并对步骤二进行修改 template<typename tFrom, typename tTo> class TypeAliaser { public: TypeAliaser(tFrom inFromValue) : mAsFromType(inFromValue) {} tTo &Get() { return mAsFromType; } union { tFrom mAsFromType; //union其实就是对让模板对数据类型的推导做了一次转换 tTo mAsToType; //例如:float是32位,那么tFrom为float,tTo为uint32_t }; }; //对步骤二的修改: template<typename T> class ByteSwapper<T, 2> { public: T Swap(T inData) const { //最后.Get()拿出来的值被推导后数据类型为uint16_t uint16_t result = ByteSwap2(TypeAliaser<T, uint16_t>(inData).Get()); //将原数据类型返回 return TypeAliaser<uint16_t, T>(result).Get(); } }; template<typename T> class ByteSwapper<T, 4> { public: T Swap(T inData) const { uint16_t result = ByteSwap4(TypeAliaser<T, uint32_t>(inData).Get()); return TypeAliaser<uint32_t, T>(result).Get(); } }; template<typename T> class ByteSwapper<T, 8> { public: T Swap(T inData) const { uint16_t result = ByteSwap8(TypeAliaser<T, uint64_t>(inData).Get()); return TypeAliaser<uint64_t, T>(result).Get(); } };