模板化字节交换

//模板化的字节交换函数 
#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();
    }
};

 

posted @ 2020-10-03 11:35  只取一瓢饮  阅读(134)  评论(0编辑  收藏  举报