lib/std/io/stream: add LimitReader (#858)

* lib/std/io/stream: add LimitReader

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>

* lib/std: more method conversions to use new receiver notation

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>

---------

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
Pierre Curto
2023-07-17 20:22:29 +02:00
committed by GitHub
parent 209d994336
commit fd5336c56e
16 changed files with 266 additions and 210 deletions

View File

@@ -21,7 +21,7 @@ struct RandomInterface
* @param [&inout] random
* @param [inout] buffer
**/
fn void Random.next_bytes(Random* random, char[] buffer)
fn void Random.next_bytes(&random, char[] buffer)
{
if (!buffer.len) return;
if (RandomNextBytesFn func = random.fns.next_bytes_fn)
@@ -50,7 +50,7 @@ fn void Random.next_bytes(Random* random, char[] buffer)
* @param [&inout] random
* @require bits >= 0 && bits <= 32
**/
fn uint Random.next(Random* random, int bits)
fn uint Random.next(&random, int bits)
{
if (bits == 0) return 0;
if (RandomNextFn func = random.fns.next_fn) return func(random, bits);
@@ -71,7 +71,7 @@ fn uint Random.next(Random* random, int bits)
/**
* @param [&inout] random
**/
fn ulong Random.next_long(Random* random)
fn ulong Random.next_long(&random)
{
char[8] buffer;
random.next_bytes(&buffer);
@@ -81,7 +81,7 @@ fn ulong Random.next_long(Random* random)
/**
* @param [&inout] random
**/
fn void Random.set_seed(Random* random, long seed)
fn void Random.set_seed(&random, long seed)
{
random.fns.seed_fn(random, &&bitcast(seed, char[8])) @inline;
}
@@ -90,7 +90,7 @@ fn void Random.set_seed(Random* random, long seed)
* @param [&inout] random
* @param [in] seed
**/
fn void Random.set_seeds(Random* random, char[] seed)
fn void Random.set_seeds(&random, char[] seed)
{
random.fns.seed_fn(random, seed);
}
@@ -98,22 +98,22 @@ fn void Random.set_seeds(Random* random, char[] seed)
/**
* @param [&inout] random
**/
fn bool Random.next_bool(Random* random)
fn bool Random.next_bool(&random)
{
return random.next(1) != 0;
}
fn float Random.next_float(Random* r)
fn float Random.next_float(&r)
{
return r.next(24) / (float)(1 << 24);
}
fn double Random.next_double(Random* r)
fn double Random.next_double(&r)
{
return (((long)(r.next(26)) << 27) + r.next(27)) * 0x1.0p-53;
}
fn uint Random.next_int(Random* r)
fn uint Random.next_int(&r)
{
return r.next(32) @inline;
}

View File

@@ -22,7 +22,7 @@ macro Matrix4f Quaternion.to_matrixf(Quaternion* q) => into_matrix(q, Matrix4f);
macro Matrix4 Quaternion.to_matrix(Quaternion* q) => into_matrix(q, Matrix4);
fn Quaternion Quaternion.nlerp(Quaternion q1, Quaternion q2, Real amount) => { .v = q1.v.lerp(q2.v, amount).normalize() };
fn Quaternion Quaternion.invert(Quaternion q)
fn Quaternion Quaternion.invert(q)
{
Real length_sq = q.v.dot(q.v);
if (length_sq <= 0) return q;
@@ -30,7 +30,7 @@ fn Quaternion Quaternion.invert(Quaternion q)
return { q.v[0] * -inv_length, q.v[1] * -inv_length, q.v[2] * -inv_length, q.v[3] * inv_length };
}
fn Quaternion Quaternion.slerp(Quaternion q1, Quaternion q2, Real amount)
fn Quaternion Quaternion.slerp(q1, Quaternion q2, Real amount)
{
Quaternion result = {};
@@ -59,7 +59,7 @@ fn Quaternion Quaternion.slerp(Quaternion q1, Quaternion q2, Real amount)
return { .v = q1v * ratio_a + q2v * ratio_b };
}
fn Quaternion Quaternion.mul(Quaternion a, Quaternion b)
fn Quaternion Quaternion.mul(a, Quaternion b)
{
return { a.i * b.l + a.l * b.i + a.j * b.k - a.k * b.j,
a.j * b.l + a.l * b.j + a.k * b.i - a.i * b.k,

View File

@@ -16,12 +16,12 @@ const MUL_LCG16 @local = 0x915d; // TODO: Find good constant
def Lcg128_64 = distinct uint128;
fn void Lcg128_64.seed(Lcg128_64* lcg, char[16] seed)
fn void Lcg128_64.seed(&lcg, char[16] seed)
{
*lcg = bitcast(seed, Lcg128_64);
}
fn ulong Lcg128_64.next(Lcg128_64* lcg)
fn ulong Lcg128_64.next(&lcg)
{
uint128* s = (uint128*)lcg;
ulong result = (ulong)(*s >> 64);
@@ -34,12 +34,12 @@ fn ulong Lcg128_64.next(Lcg128_64* lcg)
def Lcg64_32 = distinct ulong;
fn void Lcg64_32.seed(Lcg64_32* lcg, char[8] seed)
fn void Lcg64_32.seed(&lcg, char[8] seed)
{
*lcg = bitcast(seed, Lcg64_32);
}
fn uint Lcg64_32.next(Lcg64_32* lcg)
fn uint Lcg64_32.next(&lcg)
{
ulong* s = (ulong*)lcg;
uint result = (uint)(*s >> 32);
@@ -52,12 +52,12 @@ fn uint Lcg64_32.next(Lcg64_32* lcg)
def Lcg32_16 = distinct uint;
fn void Lcg32_16.seed(Lcg32_16* lcg, char[4] seed)
fn void Lcg32_16.seed(&lcg, char[4] seed)
{
*lcg = bitcast(seed, Lcg32_16);
}
fn ushort Lcg32_16.next(Lcg32_16* lcg)
fn ushort Lcg32_16.next(&lcg)
{
uint* s = (uint*)lcg;
ushort result = (ushort)(*s >> 16);
@@ -70,12 +70,12 @@ fn ushort Lcg32_16.next(Lcg32_16* lcg)
def Lcg16_8 = distinct ushort;
fn void Lcg16_8.seed(Lcg16_8* lcg, char[2] seed)
fn void Lcg16_8.seed(&lcg, char[2] seed)
{
*lcg = bitcast(seed, Lcg16_8);
}
fn char Lcg16_8.next(Lcg16_8* lcg)
fn char Lcg16_8.next(&lcg)
{
ushort* s = (ushort*)lcg;
char result = (char)(*s >> 8);

View File

@@ -9,12 +9,12 @@ const MUL_MCG16 @local = 0x93d5; // TODO: Find good constant
def Mcg128_64 = distinct uint128;
fn void Mcg128_64.seed(Mcg128_64* mcg, char[16] seed)
fn void Mcg128_64.seed(&mcg, char[16] seed)
{
*mcg = bitcast(seed, Mcg128_64) | 1;
}
fn ulong Mcg128_64.next(Mcg128_64* mcg)
fn ulong Mcg128_64.next(&mcg)
{
uint128* s = (uint128*)mcg;
ulong result = (ulong)(*s >> 64);
@@ -27,12 +27,12 @@ fn ulong Mcg128_64.next(Mcg128_64* mcg)
def Mcg64_32 = distinct ulong;
fn void Mcg64_32.seed(Mcg64_32* mcg, char[8] seed)
fn void Mcg64_32.seed(&mcg, char[8] seed)
{
*mcg = bitcast(seed, Mcg64_32) | 1;
}
fn uint Mcg64_32.next(Mcg64_32* mcg)
fn uint Mcg64_32.next(&mcg)
{
ulong* s = (ulong*)mcg;
uint result = (uint)(*s >> 32);
@@ -45,12 +45,12 @@ fn uint Mcg64_32.next(Mcg64_32* mcg)
def Mcg32_16 = distinct uint;
fn void Mcg32_16.seed(Mcg32_16* mcg, char[4] seed)
fn void Mcg32_16.seed(&mcg, char[4] seed)
{
*mcg = bitcast(seed, Mcg32_16) | 1;
}
fn ushort Mcg32_16.next(Mcg32_16* mcg)
fn ushort Mcg32_16.next(&mcg)
{
uint* s = (uint*)mcg;
ushort result = (ushort)(*s >> 16);
@@ -63,12 +63,12 @@ fn ushort Mcg32_16.next(Mcg32_16* mcg)
def Mcg16_8 = distinct ushort;
fn void Mcg16_8.seed(Mcg16_8* mcg, char[2] seed)
fn void Mcg16_8.seed(&mcg, char[2] seed)
{
*mcg = bitcast(seed, Mcg16_8) | 1;
}
fn char Mcg16_8.next(Mcg16_8* mcg)
fn char Mcg16_8.next(&mcg)
{
ushort* s = (ushort*)mcg;
char result = (char)(*s >> 8);

View File

@@ -15,12 +15,12 @@ struct Msws128 {
uint128 weyl0, weyl1;
}
fn void Msws128.seed(Msws128* msws, char[16 * 4] seed)
fn void Msws128.seed(&msws, char[16 * 4] seed)
{
*msws = bitcast(seed, Msws128);
}
fn uint128 Msws128.next(Msws128* msws)
fn uint128 Msws128.next(&msws)
{
uint128 s0 = msws.state0;
msws.state0 = msws.state0 * msws.state0 + msws.weyl0;
@@ -43,12 +43,12 @@ struct Msws64 {
ulong weyl0, weyl1;
}
fn void Msws64.seed(Msws64* msws, char[8 * 4] seed)
fn void Msws64.seed(&msws, char[8 * 4] seed)
{
*msws = bitcast(seed, Msws64);
}
fn ulong Msws64.next(Msws64* msws)
fn ulong Msws64.next(&msws)
{
ulong s0 = msws.state0;
msws.state0 = msws.state0 * msws.state0 + msws.weyl0;
@@ -71,12 +71,12 @@ struct Msws32 {
uint weyl0, weyl1;
}
fn void Msws32.seed(Msws32* msws, char[4 * 4] seed)
fn void Msws32.seed(&msws, char[4 * 4] seed)
{
*msws = bitcast(seed, Msws32);
}
fn uint Msws32.next(Msws32* msws)
fn uint Msws32.next(&msws)
{
uint s0 = msws.state0;
msws.state0 = msws.state0 * msws.state0 + msws.weyl0;
@@ -99,12 +99,12 @@ struct Msws16 {
ushort weyl0, weyl1;
}
fn void Msws16.seed(Msws16* msws, char[2 * 4] seed)
fn void Msws16.seed(&msws, char[2 * 4] seed)
{
*msws = bitcast(seed, Msws16);
}
fn ushort Msws16.next(Msws16* msws)
fn ushort Msws16.next(&msws)
{
ushort s0 = msws.state0;
msws.state0 = msws.state0 * msws.state0 + msws.weyl0;
@@ -127,12 +127,12 @@ struct Msws8 {
char weyl0, weyl1;
}
fn void Msws8.seed(Msws8* msws, char[1 * 4] seed)
fn void Msws8.seed(&msws, char[1 * 4] seed)
{
*msws = bitcast(seed, Msws8);
}
fn char Msws8.next(Msws8* msws)
fn char Msws8.next(&msws)
{
char s0 = msws.state0;
msws.state0 = msws.state0 * msws.state0 + msws.weyl0;

View File

@@ -16,12 +16,12 @@ const MUL_LCG16 @local = 0x915d; // TODO: Find good constant
def Pcg128_64 = distinct uint128;
fn void Pcg128_64.seed(Pcg128_64* pcg, char[16] seed)
fn void Pcg128_64.seed(&pcg, char[16] seed)
{
*pcg = bitcast(seed, Pcg128_64);
}
fn ulong Pcg128_64.next(Pcg128_64* pcg)
fn ulong Pcg128_64.next(&pcg)
{
const ROT_SHIFT = 64 - 6;
uint128* s = (uint128*)pcg;
@@ -36,12 +36,12 @@ fn ulong Pcg128_64.next(Pcg128_64* pcg)
def Pcg64_32 = distinct ulong;
fn void Pcg64_32.seed(Pcg64_32* pcg, char[8] seed)
fn void Pcg64_32.seed(&pcg, char[8] seed)
{
*pcg = bitcast(seed, Pcg64_32);
}
fn uint Pcg64_32.next(Pcg64_32* pcg)
fn uint Pcg64_32.next(&pcg)
{
const ROT_SHIFT = 32 - 5;
ulong* s = (ulong*)pcg;
@@ -56,12 +56,12 @@ fn uint Pcg64_32.next(Pcg64_32* pcg)
def Pcg32_16 = distinct uint;
fn void Pcg32_16.seed(Pcg32_16* pcg, char[4] seed)
fn void Pcg32_16.seed(&pcg, char[4] seed)
{
*pcg = bitcast(seed, Pcg32_16);
}
fn ushort Pcg32_16.next(Pcg32_16* pcg)
fn ushort Pcg32_16.next(&pcg)
{
const ROT_SHIFT = 16 - 4;
uint* s = (uint*)pcg;
@@ -76,12 +76,12 @@ fn ushort Pcg32_16.next(Pcg32_16* pcg)
def Pcg16_8 = distinct ushort;
fn void Pcg16_8.seed(Pcg16_8* pcg, char[2] seed)
fn void Pcg16_8.seed(&pcg, char[2] seed)
{
*pcg = bitcast(seed, Pcg16_8);
}
fn char Pcg16_8.next(Pcg16_8* pcg)
fn char Pcg16_8.next(&pcg)
{
const ROT_SHIFT = 8 - 3;
ushort* s = (ushort*)pcg;

View File

@@ -12,12 +12,12 @@ const ODD_PHI8 @local = 0x9f;
def Sfc128 = distinct uint128[4];
fn void Sfc128.seed(Sfc128* sfc, char[16 * 4] seed)
fn void Sfc128.seed(&sfc, char[16 * 4] seed)
{
*sfc = bitcast(seed, Sfc128);
}
fn uint128 Sfc128.next(Sfc128* sfc) // TODO: Find good constant
fn uint128 Sfc128.next(&sfc) // TODO: Find good constant
{
uint128* s = (uint128[4]*)sfc;
uint128 result = s[0] + s[1] + s[3];
@@ -33,12 +33,12 @@ fn uint128 Sfc128.next(Sfc128* sfc) // TODO: Find good constant
def Sfc64 = distinct ulong[4];
fn void Sfc64.seed(Sfc64* sfc, char[8 * 4] seed)
fn void Sfc64.seed(&sfc, char[8 * 4] seed)
{
*sfc = bitcast(seed, Sfc64);
}
fn ulong Sfc64.next(Sfc64* sfc)
fn ulong Sfc64.next(&sfc)
{
ulong* s = (ulong[4]*)sfc;
ulong result = s[0] + s[1] + s[3];
@@ -54,12 +54,12 @@ fn ulong Sfc64.next(Sfc64* sfc)
def Sfc32 = distinct uint[4];
fn void Sfc32.seed(Sfc32* sfc, char[4 * 4] seed)
fn void Sfc32.seed(&sfc, char[4 * 4] seed)
{
*sfc = bitcast(seed, Sfc32);
}
fn uint Sfc32.next(Sfc32* sfc)
fn uint Sfc32.next(&sfc)
{
uint* s = (uint[4]*)sfc;
uint result = s[0] + s[1] + s[3];
@@ -75,12 +75,12 @@ fn uint Sfc32.next(Sfc32* sfc)
def Sfc16 = distinct ushort[4];
fn void Sfc16.seed(Sfc16* sfc, char[2 * 4] seed)
fn void Sfc16.seed(&sfc, char[2 * 4] seed)
{
*sfc = bitcast(seed, Sfc16);
}
fn ushort Sfc16.next(Sfc16* sfc)
fn ushort Sfc16.next(&sfc)
{
ushort* s = (ushort[4]*)sfc;
ushort result = s[0] + s[1] + s[3];
@@ -96,12 +96,12 @@ fn ushort Sfc16.next(Sfc16* sfc)
def Sfc8 = distinct char[4];
fn void Sfc8.seed(Sfc8* sfc, char[1 * 4] seed)
fn void Sfc8.seed(&sfc, char[1 * 4] seed)
{
*sfc = bitcast(seed, Sfc8);
}
fn char Sfc8.next(Sfc8* sfc) // TODO: Find better constants
fn char Sfc8.next(&sfc) // TODO: Find better constants
{
char* s = (char[4]*)sfc;
char result = s[0] + s[1] + s[3];

View File

@@ -11,23 +11,23 @@ RandomInterface simple_random_interface = {
.next_fn = fn (random, bits) => ((SimpleRandom*)random.state).next(bits)
};
fn Random SimpleRandom.as_random(SimpleRandom* random)
fn Random SimpleRandom.as_random(&random)
{
return { .fns = simple_random_interface, .state = random };
}
fn uint SimpleRandom.next(SimpleRandom* r, int bits)
fn uint SimpleRandom.next(&r, int bits)
{
ulong nextseed = ((ulong)*r * SIMPLE_RANDOM_MULTIPLIER + SIMPLE_RANDOM_ADDEND) & SIMPLE_RANDOM_MASK;
*r = (SimpleRandom)nextseed;
return (uint)(nextseed >> (48 - bits));
}
fn void SimpleRandom.set_seed(SimpleRandom* r, ulong seed)
fn void SimpleRandom.set_seed(&r, ulong seed)
{
*r = (SimpleRandom)((seed ^ SIMPLE_RANDOM_MULTIPLIER) & SIMPLE_RANDOM_MASK);
}
fn void SimpleRandom.set_seeds(SimpleRandom* r, char[] seed)
fn void SimpleRandom.set_seeds(&r, char[] seed)
{
char[8] full;
foreach (i, c : seed)