mirror of
https://github.com/dlang/phobos.git
synced 2025-04-27 13:40:20 +03:00
Merge pull request #7032 from n8sh/bitmanipConsolidateImpl
Pare down std.bitmanip's 13 private impl functions to 4 merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
This commit is contained in:
commit
2b94eb88d6
1 changed files with 41 additions and 126 deletions
167
std/bitmanip.d
167
std/bitmanip.d
|
@ -2724,16 +2724,15 @@ public:
|
|||
T swapEndian(T)(const T val) @safe pure nothrow @nogc
|
||||
if (isIntegral!T || isSomeChar!T || isBoolean!T)
|
||||
{
|
||||
import core.bitop : bswap;
|
||||
static if (val.sizeof == 1)
|
||||
return val;
|
||||
else static if (isUnsigned!T)
|
||||
return swapEndianImpl(val);
|
||||
else static if (isIntegral!T)
|
||||
return cast(T) 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 if (T.sizeof == 2)
|
||||
return cast(T) (((val & 0xff00U) >> 8) | ((val & 0x00ffU) << 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(ulong) val);
|
||||
else
|
||||
static assert(0, T.stringof ~ " unsupported by swapEndian.");
|
||||
}
|
||||
|
@ -2754,25 +2753,6 @@ if (isIntegral!T || isSomeChar!T || isBoolean!T)
|
|||
assert(ulong(10).swapEndian == 720575940379279360);
|
||||
}
|
||||
|
||||
private ushort swapEndianImpl(ushort val) @safe pure nothrow @nogc
|
||||
{
|
||||
return ((val & 0xff00U) >> 8) |
|
||||
((val & 0x00ffU) << 8);
|
||||
}
|
||||
|
||||
private uint swapEndianImpl(uint val) @trusted pure nothrow @nogc
|
||||
{
|
||||
import core.bitop : bswap;
|
||||
return bswap(val);
|
||||
}
|
||||
|
||||
private ulong swapEndianImpl(ulong val) @trusted pure nothrow @nogc
|
||||
{
|
||||
import core.bitop : bswap;
|
||||
immutable ulong res = bswap(cast(uint) val);
|
||||
return res << 32 | bswap(cast(uint)(val >> 32));
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
import std.meta;
|
||||
|
@ -2894,7 +2874,10 @@ if (__traits(isIntegral, T))
|
|||
auto nativeToBigEndian(T)(const T val) @safe pure nothrow @nogc
|
||||
if (canSwapEndianness!T)
|
||||
{
|
||||
return nativeToBigEndianImpl(val);
|
||||
version (LittleEndian)
|
||||
return nativeToEndianImpl!true(val);
|
||||
else
|
||||
return nativeToEndianImpl!false(val);
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2921,34 +2904,26 @@ if (canSwapEndianness!T)
|
|||
assert(cd == bigEndianToNative!double(swappedCD));
|
||||
}
|
||||
|
||||
private auto nativeToBigEndianImpl(T)(T val) @safe pure nothrow @nogc
|
||||
if (isIntegral!T || isSomeChar!T || isBoolean!T)
|
||||
private auto nativeToEndianImpl(bool swap, T)(const T val) @safe pure nothrow @nogc
|
||||
if (__traits(isIntegral, T))
|
||||
{
|
||||
if (!__ctfe)
|
||||
{
|
||||
version (LittleEndian)
|
||||
static if (swap)
|
||||
return EndianSwapper!T(swapEndian(val)).array;
|
||||
else
|
||||
return EndianSwapper!T(val).array;
|
||||
}
|
||||
else
|
||||
{
|
||||
version (LittleEndian)
|
||||
// Can't use EndianSwapper in CTFE.
|
||||
static if (swap)
|
||||
return ctfeBytes(swapEndian(val));
|
||||
else
|
||||
return ctfeBytes(val);
|
||||
}
|
||||
}
|
||||
|
||||
private auto nativeToBigEndianImpl(T)(T val) @safe pure nothrow @nogc
|
||||
if (isFloatOrDouble!T)
|
||||
{
|
||||
version (LittleEndian)
|
||||
return floatEndianImpl!(T, true)(val);
|
||||
else
|
||||
return floatEndianImpl!(T, false)(val);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
import std.meta;
|
||||
|
@ -3038,7 +3013,10 @@ if (isFloatOrDouble!T)
|
|||
T bigEndianToNative(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc
|
||||
if (canSwapEndianness!T && n == T.sizeof)
|
||||
{
|
||||
return bigEndianToNativeImpl!(T, n)(val);
|
||||
version (LittleEndian)
|
||||
return endianToNativeImpl!(true, T, n)(val);
|
||||
else
|
||||
return endianToNativeImpl!(false, T, n)(val);
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -3053,37 +3031,6 @@ if (canSwapEndianness!T && n == T.sizeof)
|
|||
assert(c == bigEndianToNative!dchar(swappedC));
|
||||
}
|
||||
|
||||
private T bigEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc
|
||||
if ((isIntegral!T || isSomeChar!T || isBoolean!T) &&
|
||||
n == T.sizeof)
|
||||
{
|
||||
if (!__ctfe)
|
||||
{
|
||||
EndianSwapper!T es = { array: val };
|
||||
version (LittleEndian)
|
||||
return swapEndian(es.value);
|
||||
else
|
||||
return es.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
version (LittleEndian)
|
||||
return swapEndian(ctfeRead!T(val));
|
||||
else
|
||||
return ctfeRead!T(val);
|
||||
}
|
||||
}
|
||||
|
||||
private T bigEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc
|
||||
if (isFloatOrDouble!T && n == T.sizeof)
|
||||
{
|
||||
version (LittleEndian)
|
||||
return cast(T) floatEndianImpl!(n, true)(val);
|
||||
else
|
||||
return cast(T) floatEndianImpl!(n, false)(val);
|
||||
}
|
||||
|
||||
|
||||
/++
|
||||
Converts the given value from the native endianness to little endian and
|
||||
returns it as a `ubyte[n]` where `n` is the size of the given type.
|
||||
|
@ -3096,7 +3043,10 @@ if (isFloatOrDouble!T && n == T.sizeof)
|
|||
auto nativeToLittleEndian(T)(const T val) @safe pure nothrow @nogc
|
||||
if (canSwapEndianness!T)
|
||||
{
|
||||
return nativeToLittleEndianImpl(val);
|
||||
version (BigEndian)
|
||||
return nativeToEndianImpl!true(val);
|
||||
else
|
||||
return nativeToEndianImpl!false(val);
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -3111,34 +3061,6 @@ if (canSwapEndianness!T)
|
|||
assert(d == littleEndianToNative!double(swappedD));
|
||||
}
|
||||
|
||||
private auto nativeToLittleEndianImpl(T)(T val) @safe pure nothrow @nogc
|
||||
if (isIntegral!T || isSomeChar!T || isBoolean!T)
|
||||
{
|
||||
if (!__ctfe)
|
||||
{
|
||||
version (BigEndian)
|
||||
return EndianSwapper!T(swapEndian(val)).array;
|
||||
else
|
||||
return EndianSwapper!T(val).array;
|
||||
}
|
||||
else
|
||||
{
|
||||
version (BigEndian)
|
||||
return ctfeBytes(swapEndian(val));
|
||||
else
|
||||
return ctfeBytes(val);
|
||||
}
|
||||
}
|
||||
|
||||
private auto nativeToLittleEndianImpl(T)(T val) @safe pure nothrow @nogc
|
||||
if (isFloatOrDouble!T)
|
||||
{
|
||||
version (BigEndian)
|
||||
return floatEndianImpl!(T, true)(val);
|
||||
else
|
||||
return floatEndianImpl!(T, false)(val);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
{
|
||||
import std.meta;
|
||||
|
@ -3201,7 +3123,10 @@ if (isFloatOrDouble!T)
|
|||
T littleEndianToNative(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc
|
||||
if (canSwapEndianness!T && n == T.sizeof)
|
||||
{
|
||||
return littleEndianToNativeImpl!T(val);
|
||||
version (BigEndian)
|
||||
return endianToNativeImpl!(true, T, n)(val);
|
||||
else
|
||||
return endianToNativeImpl!(false, T, n)(val);
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -3216,38 +3141,27 @@ if (canSwapEndianness!T && n == T.sizeof)
|
|||
assert(c == littleEndianToNative!dchar(swappedC));
|
||||
}
|
||||
|
||||
private T littleEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc
|
||||
if ((isIntegral!T || isSomeChar!T || isBoolean!T) &&
|
||||
n == T.sizeof)
|
||||
private T endianToNativeImpl(bool swap, T, size_t n)(ubyte[n] val) @nogc nothrow pure @safe
|
||||
if (__traits(isIntegral, T) && n == T.sizeof)
|
||||
{
|
||||
if (!__ctfe)
|
||||
{
|
||||
EndianSwapper!T es = { array: val };
|
||||
version (BigEndian)
|
||||
static if (swap)
|
||||
return swapEndian(es.value);
|
||||
else
|
||||
return es.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
version (BigEndian)
|
||||
static if (swap)
|
||||
return swapEndian(ctfeRead!T(val));
|
||||
else
|
||||
return ctfeRead!T(val);
|
||||
}
|
||||
}
|
||||
|
||||
private T littleEndianToNativeImpl(T, size_t n)(ubyte[n] val) @safe pure nothrow @nogc
|
||||
if (((isFloatOrDouble!T) &&
|
||||
n == T.sizeof))
|
||||
{
|
||||
version (BigEndian)
|
||||
return floatEndianImpl!(n, true)(val);
|
||||
else
|
||||
return floatEndianImpl!(n, false)(val);
|
||||
}
|
||||
|
||||
private auto floatEndianImpl(T, bool swap)(T val) @trusted pure nothrow @nogc
|
||||
private auto nativeToEndianImpl(bool swap, T)(const T val) @trusted pure nothrow @nogc
|
||||
if (isFloatOrDouble!T)
|
||||
{
|
||||
if (!__ctfe)
|
||||
|
@ -3269,24 +3183,25 @@ if (isFloatOrDouble!T)
|
|||
}
|
||||
}
|
||||
|
||||
private auto floatEndianImpl(size_t n, bool swap)(ubyte[n] val) @trusted pure nothrow @nogc
|
||||
if (n == 4 || n == 8)
|
||||
private auto endianToNativeImpl(bool swap, T, size_t n)(ubyte[n] val) @trusted pure nothrow @nogc
|
||||
if (isFloatOrDouble!T && n == T.sizeof)
|
||||
{
|
||||
static if (n == 4) { alias Float = float; alias Int = uint; }
|
||||
else static if (n == 8) { alias Float = double; alias Int = ulong; }
|
||||
if (!__ctfe)
|
||||
{
|
||||
EndianSwapper!Float es = { array: val };
|
||||
EndianSwapper!T es = { array: val };
|
||||
static if (swap)
|
||||
es.intValue = swapEndian(es.intValue);
|
||||
return es.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Int x = ctfeRead!Int(val);
|
||||
static if (n == 4)
|
||||
uint x = ctfeRead!uint(val);
|
||||
else static if (n == 8)
|
||||
ulong x = ctfeRead!ulong(val);
|
||||
static if (swap)
|
||||
x = swapEndian(x);
|
||||
return *cast(const Float*) &x;
|
||||
return *cast(T*) &x;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue