Last active
November 15, 2016 00:39
-
-
Save UplinkCoder/fed000f5ca41ad3d65d59a7a63d5ef6f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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