Skip to content

Instantly share code, notes, and snippets.

@UplinkCoder
Last active November 15, 2016 00:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save UplinkCoder/fed000f5ca41ad3d65d59a7a63d5ef6f to your computer and use it in GitHub Desktop.
Save UplinkCoder/fed000f5ca41ad3d65d59a7a63d5ef6f to your computer and use it in GitHub Desktop.
uint[] neededArraySize(uint size)
{
return (size - 1) / 4 + 2 + !(size & 3);
}
uint[] stringToUintArray(string s)
{
if (s.length == 0)
{
return [0u, 0u];
}
uint[] result;
uint size = cast(uint)s.length;
immutable SizeMinusOne = size - 1;
immutable SizeOverFour = SizeMinusOne / 4;
result.length = SizeOverFour + 2 + !(size & 3);
immutable char* _string = &s[0];
result[0] = size;
foreach (i; 0 .. SizeOverFour)
{
result[i + 1] = *(_string + i * 4) | *(_string + i * 4 + 1) << 8 | *(_string + i * 4 + 2) << 16 | *(_string + i * 4 + 3) << 24;
}
final switch (SizeMinusOne & 3)
{
case 3:
{
result[1 + SizeOverFour] |= *(_string + SizeOverFour * 4 + 3) << 24;
goto case 2;
}
case 2:
{
result[1 + SizeOverFour] |= *(_string + SizeOverFour * 4 + 2) << 16;
goto case 1;
}
case 1:
{
result[1 + SizeOverFour] |= *(_string + SizeOverFour * 4 + 1) << 8;
goto case 0;
}
case 0:
{
result[1 + SizeOverFour] |= *(_string + SizeOverFour * 4);
}
}
if (!(size & 3))
{
result[SizeOverFour + 2] = 0;
}
return result;
}
string uIntArrayToString(uint[] strarr)
{
char[] result;
uint length = strarr[0];
if (length == 0)
{
return "";
}
result.length = length;
foreach (p; 0 .. length)
{
result[p] = strarr[1 + p / 4] >> (p & 3) * 8 & 255;
}
return result.idup;
}
alias stou = stringToUintArray;
alias utos = uIntArrayToString;
pragma (msg, stringToUintArray("") == [0, 0]);
pragma (msg, stringToUintArray("Hello World").length);
pragma (msg, stringToUintArray("H").length);
pragma (msg, stringToUintArray("He").length);
pragma (msg, stringToUintArray("Hel").length);
pragma (msg, stringToUintArray("Hell").length);
static assert(uIntArrayToString(stringToUintArray("Hel")) == "Hel");
static assert((*(stringToUintArray("Hello World1").ptr + 3) & 4278190080u) == '1' << 24);
static assert((*(stringToUintArray("Hello World").ptr + 3) & 255) == 'r');
static assert((*(stringToUintArray("Hello World").ptr + 2) & 255) == 'o');
static assert((*(stringToUintArray("Hello World").ptr + 1) & 255) == 'H');
static assert(*stringToUintArray("Hello World").ptr == "Hello World".length);
static immutable hellu = stou("Hell");
static immutable worldu = stou("World");
pragma (msg, neededArraySize("Hello".length));
auto strcat(const uint[] a, const uint[] b, uint aLength = 0, uint bLength = 0)
{
aLength = a[0];
bLength = b[0];
uint resultLength = a[0] + b[0];
uint[] result;
result.length = neededArraySize(resultLength);
result[0] = resultLength;
auto resultPosition = 1;
auto aMinusOne = !(aLength & 3);
foreach (p, ca; a[1..$ - aMinusOne])
{
result[resultPosition++] = ca;
}
auto bMinusOne = !(bLength & 3);
immutable uint offset = aLength & 3;
if (offset)
{
immutable OffsetTimesEight = offset * 8;
immutable FourMinusOffsetTimesEight = (4 - offset) * 8;
immutable uint FirstAnd = (1 << FourMinusOffsetTimesEight) - 1;
immutable uint SecondAnd = (~FirstAnd) & uint.max;
resultPosition--;
foreach (p, cb; b[1..$])
{
result[resultPosition++] |= (cb & FirstAnd) << OffsetTimesEight;
if (resultPosition == result.length)
break;
result[resultPosition] |= (cb & SecondAnd) >> FourMinusOffsetTimesEight;
}
}
else
{
foreach (p, cb; b[1..$ - bMinusOne])
{
result[resultPosition++] = cb;
}
}
return result;
}
pragma (msg, utos(strcat(hellu, worldu)));
pragma (msg, stou("123World"));
static assert(utos(strcat(stou("1234"), stou("ABCDA"))) == "1234ABCDA");
static assert(utos(strcat(stou("123"), stou("ABCDA"))) == "123ABCDA");
static assert(utos(strcat(stou("12"), stou("ABCDA"))) == "12ABCDA");
static assert((1u << 2 * 8) - 1 == (ushort).max);
pragma (msg, ~((1u << 1 * 8) - 1));
uint[] strcat_(const uint[] a, const uint[] b, uint[] result = [], uint aLength = 0, uint bLength = 0, uint aDollar = 0, uint bDollar = 0, uint resultLength = 0, uint resultPosition = 1, uint offset = 0, uint OffsetTimesEight = 0, uint FourMinusOffsetTimesEight = 0, uint FirstAnd = 0, uint SecondAnd = 0, uint ai = 1, uint bi = 1, uint ca = 0, uint cb =0)
{
aLength = a[0];
bLength = b[0];
aDollar = cast(uint) a.length;
bDollar = cast (uint) b.length;
resultLength = aLength + bLength;
result.length = (resultLength- 1) / 4 + 2 + ((resultLength & 3) == 0);
result[0] = resultLength;
offset = aLength & 3;
for(ca = a[ai]; ai != aDollar - (offset == 0); ai++)
{
result[resultPosition++] = ca;
}
if (offset)
{
OffsetTimesEight = offset * 8;
FourMinusOffsetTimesEight = (4 - offset) * 8;
FirstAnd = (1 << FourMinusOffsetTimesEight) - 1;
SecondAnd = (~FirstAnd) & uint.max;
resultPosition--;
for (cb = b[bi]; bi != bDollar; bi++)
{
result[resultPosition++] |= (cb & FirstAnd) << OffsetTimesEight;
if (resultPosition == result.length)
break;
result[resultPosition] |= (cb & SecondAnd) >> FourMinusOffsetTimesEight;
}
}
else
{
for(cb = a[bi]; bi != bDollar; bi++)
{
result[resultPosition++] = cb;
}
}
return result;
}
pragma(msg, strcat_([1,'a'], [1,'b']));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment