<div class="gmail_quote">On Sat, Jul 16, 2011 at 2:51 PM, Jonathan M Davis <span dir="ltr"><<a href="mailto:jmdavisProg@gmx.com">jmdavisProg@gmx.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

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