Byte Order Swapping Function

Christian Manning cmanning999 at gmail.com
Sun Jul 17 06:32:21 PDT 2011


Christian Manning wrote:

> How about this?:
> 
> private template Eqsize(T) {
>     static if (T.sizeof == 4) {
>         alias uint S;
>     }
>     else static if (T.sizeof == 8) {
>         alias ulong S;
>     }
> }
> 
> private union IntFloat {
>     uint _int;
>     float _float;
> }
> 
> private union IntDouble {
>     ulong _long;
>     double _double;
> }
> 
> T byteSwap(T)(T val) if (isIntegral!T || isSomeChar!T) {
>     static if (T.sizeof == 2) {
>         return cast(T) ((cast(ushort) val >> 8) | (cast(ushort) val <<
>         8));
>     }
>     else static if (T.sizeof == 4) {
>         return cast(T) bswap(cast(uint) val);
>     }
>     else static if (T.sizeof == 8) {
>         return cast(T)bswap(cast(uint) (val >> 32)) |
>             (cast(T)bswap(cast(uint) val) << 32);
>     }
> }
> 
> Eqsize!(T).S byteSwap(T)(T val) if (isFloatingPoint!T) {
>     static if (T.sizeof == 4) {
>         IntFloat _if;
>         _if._float = val;
>         _if._int = bswap(_if._int);
>         return _if._int;
>     }
>     else static if (T.sizeof == 8) {
>         IntDouble id;
>         id._double = val;
>         id._long = byteSwap(id._long);
>         return id._long;
>     }
> }
> 
> unittest {
>     float a = 45.17249;
>     IntFloat _if;
>     _if._int = byteSwap(byteSwap(a));
>     assert(a is _if._float);
>     assert(a == _if._float);
> 
>     double b = 835.48502;
>     IntDouble id;
>     id._long = cast(ulong) byteSwap(byteSwap(b));
>     assert(b is id._double);
>     assert(b == id._double);
> 
>     long c = 0x0102040880402010;
>     long d = 0x1020408008040201;
>     assert(byteSwap(c) == d);
>     assert(byteSwap(c) is d);
>     assert(byteSwap(byteSwap(c)) == c);
>     assert(byteSwap(byteSwap(c)) is c);
> 
>     assert(byteSwap(cast(short) -45) == -11265);
>     assert(byteSwap(cast(short) -45) is -11265);
> 
>     assert(byteSwap(0x18244281) == 0x81422418);
>     assert(byteSwap(0x18244281) is 0x81422418);
> }
> 
> T bigEndianToNative(T)(T val) if (isNumeric!T || isSomeChar!T) {
>     static if (endian == Endian.BigEndian) {
>         return val;
>     }
>     else {
>         return byteSwap(val);
>     }
> }
> 
> alias bigEndianToNative nativeToBigEndian;
> 
> T littleEndianToNative(T)(T val) if (isNumeric!T || isSomeChar!T) {
>     static if (endian == Endian.LittleEndian) {
>         return val;
>     }
>     else {
>         return byteSwap(val);
>     }
> }
> 
> alias littleEndianToNative nativeToLittleEndian;

Forgot to change bigEndianToNative and littleEndianToNative, woops. You get 
the idea though.


More information about the Digitalmars-d mailing list