use APD for ∾list

This commit is contained in:
dzaima 2023-04-28 20:17:44 +03:00
parent 5aa896ab38
commit 7a501ffbdf
3 changed files with 27 additions and 36 deletions

View File

@ -762,21 +762,9 @@ B join_c1(B t, B x) {
if (rm==0) thrM("∾: Some item rank must be equal or greater than rank of argument");
usz csz = shProd(esh, 0, rr-1);
MAKE_MUT(r, cam*csz);
usz ri = 0;
for (usz i = 0; i < xia; i++) {
B c = GetU(x, i);
if (isArr(c)) {
usz cia = IA(c);
mut_copy(r, ri, c, 0, cia);
ri+= cia;
} else {
mut_set(r, ri, inc(c));
ri++;
}
}
assert(ri==cam*csz);
Arr* ra = mut_fp(r);
M_APD_TOT(r, cam*csz);
for (usz i = 0; i < xia; i++) APD(r, GetU(x, i));
Arr* ra = APD_TOT_GET(r);
usz* sh = arr_shAlloc(ra, rr);
if (sh) {
sh[0] = cam;

View File

@ -496,33 +496,36 @@ ApdFn* apd_tot_fns[]; ApdFn* apd_sh0_fns[]; ApdFn* apd_sh1_fns[]; ApdFn* apd_
#define APD_POS_1() m->obj->ia
#define APD_POS(EB) APD_CAT(APD_POS_,EB)()
#define APD_MK0(E, EB, TY, TARR, CIA, CS) \
NOINLINE void apd_##TY##_##E(ApdMut* m, B x) { \
usz cia=CIA; CS; u8 xe=TI(x,elType); (void)xe; \
if (RARE(!(TARR))) { \
apd_widen(m, x, apd_##TY##_fns); return; \
} \
APD_OR_FILL(EB, x); \
usz p0 = APD_POS(EB); APD_POS(EB) = p0+cia; \
COPY_TO_2(m->a, E, p0, x, xe, cia); \
#define APD_WIDEN(TY) do { apd_widen(m, x, apd_##TY##_fns); return; } while(0)
#define APD_INC_POS(EB)
#define APD_MK0(E, FEB, EB, TY, TARR, CIA, T0, CS) \
NOINLINE void apd_##TY##_##E(ApdMut* m, B x) { T0 \
usz cia=CIA; CS; u8 xe=TI(x,elType); (void)xe; \
if (RARE(!(TARR))) APD_WIDEN(TY); \
APD_OR_FILL(FEB, x); \
usz p0 = APD_POS(EB); APD_POS(EB) = p0+cia; \
COPY_TO_2(m->a, E, p0, x, xe, cia); \
}
#define APD_SH1_CHK(N) if (RARE(isAtm(x) || RNK(x)!=1 || cia!=IA(x) )) { apd_sh_fail(m,x,N); return; }
#define APD_SHH_CHK(N) if (RARE(isAtm(x) || RNK(x)!=m->cr || !eqShPart(m->csh, SH(x), m->cr))) { apd_sh_fail(m,x,N); return; }
#define APD_MK(E, EB, W, TATOM, TARR) \
APD_MK0(E, EB, tot, TARR, IA(x), ) \
APD_MK0(E, EB, sh1, TARR, m->cia, APD_SH1_CHK(1)) \
APD_MK0(E, EB, sh2, TARR, m->cia, assert(m->cr>=2); APD_SHH_CHK(2)) \
#define APD_WATOM(N, EB, TATOM, WATOM) \
if (RARE(!TATOM)) APD_WIDEN(N); \
usz p0 = APD_POS(EB); \
APD_POS(EB) = p0+1; \
void* a = m->a; WATOM;
#define APD_MK(E, EB, WATOM, TATOM, TARR) \
APD_MK0(E, EB, EB, sh1, TARR, m->cia, , APD_SH1_CHK(1)) \
APD_MK0(E, EB, EB, sh2, TARR, m->cia, , assert(m->cr>=2); APD_SHH_CHK(2)) \
APD_MK0(E, 0, EB, tot, TARR, IA(x), if (isAtm(x)) { APD_WATOM(tot, EB, TATOM, WATOM); return; }, if (cia==0) return; ) \
NOINLINE void apd_sh0_##E(ApdMut* m, B x) { \
APD_OR_FILL(EB, x); \
if (isArr(x)) { \
if (RARE(RNK(x)!=0)) { apd_sh_fail(m,x,0); return; } \
x = IGetU(x,0); \
} \
if (RARE(!TATOM)) { apd_widen(m, x, apd_sh0_fns); return; } \
usz p0 = APD_POS(EB); \
APD_POS(EB) = p0+1; \
void* a = m->a; W; \
APD_WATOM(sh0, EB, TATOM, WATOM); \
}
APD_MK(bit, 0, bitp_set((u64*)a,p0,o2bG(x)), q_bit(x), xe==el_bit)
@ -554,7 +557,7 @@ SHOULD_INLINE Arr* apd_setArr(ApdMut* m, usz ia, u8 xe) {
return m->obj;
}
NOINLINE void apd_tot_init(ApdMut* m, B x) {
u8 xe = TI(x,elType);
u8 xe = isArr(x)? TI(x,elType) : selfElType(x);
m->apd = apd_tot_fns[xe];
Arr* a = apd_setArr(m, m->ia0, xe);
if (xe==el_B) { a->ia = 0; NOGC_E; }

View File

@ -258,10 +258,10 @@ ApdFn apd_tot_init, apd_sh_init;
#else
#define M_APD_BASE(M) ApdMut M;
#endif
#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // assumes elements will be arrays; end gives uninitialized shape
#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // appended things can be anything, will error on invalid; end gives full shape; rsh must be alive until at least the first APD call
#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // end gives uninitialized shape
#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // end gives full shape; will error on invalid at the end; rsh must be alive until at least the first APD call
#define M_APD_SH1(M, RIA) usz M##_sh0 = (RIA); M_APD_SH(M, 1, &M##_sh0);
#define APD(M, A) M.apd(&M, A) // doesn't consume A
#define APDD(M, A) ({ B av_ = (A); M.apd(&M, av_); dec(av_); }) // consumes A
#define APD_SH_GET(M, TY) (M.end(&M, TY))
#define APD_TOT_GET(M) ({ NOGC_E; M.obj; })
#define APD_TOT_GET(M) (M.obj)