On Saturday 16 July 2011 15:38:29 Andrei Alexandrescu wrote: > Just paste the code here.
This is what I have at the moment: import core.bitop; /++ Swaps the endianness of the given value. Any integral value, character, or floating point value is accepted. +/ T swapEndian(T)(T val) if(isNumeric!T || isSomeChar!T) { static if(val.sizeof == 1) return val; else static if(isUnsigned!T || isFloatingPoint!T) return swapEndianImpl(val); else static if(isIntegral!T) return swapEndianImpl(cast(Unsigned!T) val); else static if(is(Unqual!T == wchar)) return cast(T)swapEndian(cast(ushort)val); else static if(is(Unqual!T == dchar)) return cast(T)swapEndian(cast(uint)val); else static assert(0, T.stringof ~ " unsupported by swapEndian."); } private T swapEndianImpl(T)(T val) if(is(Unqual!T == ushort)) { return ((val & 0xff00U) >> 8) | ((val & 0x00ffU) << 8); } private T swapEndianImpl(T)(T val) if(is(Unqual!T == uint)) { return bswap(val); } private T swapEndianImpl(T)(T val) if(is(Unqual!T == ulong)) { return ((val & 0xff00000000000000UL) >> 56) | ((val & 0x00ff000000000000UL) >> 40) | ((val & 0x0000ff0000000000UL) >> 24) | ((val & 0x000000ff00000000UL) >> 8) | ((val & 0x00000000ff000000UL) << 8) | ((val & 0x0000000000ff0000UL) << 24) | ((val & 0x000000000000ff00UL) << 40) | ((val & 0x00000000000000ffUL) << 56); } private T swapEndianImpl(T)(T val) if(isFloatingPoint!T) { import std.algorithm; union Union { Unqual!T _floating; ubyte[T.sizeof] _array; } Union u; u._floating = val; std.algorithm.reverse(u._array[]); return u._floating; } unittest { import std.stdio; import std.typetuple; foreach(T; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, char, wchar, dchar, float, double, real)) { scope(failure) writefln("Failed type: %s", T.stringof); T val; const T cval; immutable T ival; assert(swapEndian(swapEndian(val)) == val); assert(swapEndian(swapEndian(cval)) == cval); assert(swapEndian(swapEndian(ival)) == ival); assert(swapEndian(swapEndian(T.min)) == T.min); assert(swapEndian(swapEndian(T.max)) == T.max); static if(isSigned!T) assert(swapEndian(swapEndian(cast(T)0)) == 0); } } I think that the problem is a combination of NaN and real. If I change the first three tests (which all test using init) to use is, then all of the tests pass until real is tested with T.max, and it's doesn't survive being swapped twice). So, maybe something special needs to be done for NaN, and the issue with real may involve issues with padding. I don't know. - Jonathan M Davis