diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 5eb430ca..7dcb30cc 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -7,12 +7,11 @@ B memberOf_c1(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0"); usz n = *SH(x); if (n==0) { decG(x); return emptyIVec(); } - if (RNK(x)>1) x = toCells(x); - u8 xe = TI(x,elType); - if (elChr(xe)) xe -= el_c8-el_i8; + u8 lw = cellWidthLog(x); + void* xv = tyany_ptr(x); #define BRUTE(T) \ - i##T* xp = tyany_ptr(x); \ + i##T* xp = xv; \ u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \ for (usz i=1; i8 && n3*n?tn:3*n)+(2*rx+1)*sizeof(usz))); @@ -81,6 +80,7 @@ B memberOf_c1(B t, B x) { } #undef BRUTE + if (RNK(x)>1) x = toCells(x); u64* rp; B r = m_bitarrv(&rp, n); H_Sb* set = m_Sb(64); SGetU(x) @@ -94,12 +94,11 @@ B count_c1(B t, B x) { usz n = *SH(x); if (n==0) { decG(x); return emptyIVec(); } if (n>(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported"); - if (RNK(x)>1) x = toCells(x); - u8 xe = TI(x,elType); - if (elChr(xe)) xe -= el_c8-el_i8; + u8 lw = cellWidthLog(x); + void* xv = tyany_ptr(x); #define BRUTE(T) \ - i##T* xp = tyany_ptr(x); \ + i##T* xp = xv; \ i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ for (usz i=1; i8 && nn?tn:n)+(2*rx+1)*sizeof(usz))); @@ -169,6 +168,7 @@ B count_c1(B t, B x) { } #undef BRUTE + if (RNK(x)>1) x = toCells(x); i32* rp; B r = m_i32arrv(&rp, n); H_b2i* map = m_b2i(64); SGetU(x) @@ -186,12 +186,11 @@ B indexOf_c1(B t, B x) { usz n = *SH(x); if (n==0) { decG(x); return emptyIVec(); } if (n>(usz)I32_MAX+1) thrM("⊐: Argument length >2⋆31 not supported"); - if (RNK(x)>1) x = toCells(x); - u8 xe = TI(x,elType); - if (elChr(xe)) xe -= el_c8-el_i8; + u8 lw = cellWidthLog(x); + void* xv = tyany_ptr(x); #define BRUTE(T) \ - i##T* xp = tyany_ptr(x); \ + i##T* xp = xv; \ i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ TALLOC(i##T, uniq, n); uniq[0]=xp[0]; \ for (usz i=1, u=1; i8 && n1) x = toCells(x); i32* rp; B r = m_i32arrv(&rp, n); H_b2i* map = m_b2i(64); SGetU(x) diff --git a/src/core/arrFns.h b/src/core/arrFns.h index 10c6e109..33f219a6 100644 --- a/src/core/arrFns.h +++ b/src/core/arrFns.h @@ -54,4 +54,17 @@ extern u8 elType2type[]; extern u8 elTypeWidth[]; #define elWidth(X) elTypeWidth[X] extern u8 arrTypeWidthLog[]; -#define arrTypeWidthLog(X) arrTypeWidthLog[X] \ No newline at end of file +#define arrTypeWidthLog(X) arrTypeWidthLog[X] +extern u8 arrTypeBitsLog[]; +#define arrTypeBitsLog(X) arrTypeBitsLog[X] + +// Log of width in bits: max of 7, and also return 7 if not power of 2 +static u8 cellWidthLog(B x) { + assert(isArr(x) && RNK(x)>=1); + u8 lw = arrTypeBitsLog(TY(x)); + if (LIKELY(RNK(x)==1)) return lw; + usz csz = arr_csz(x); + if (csz & (csz-1)) return 7; // Not power of 2 + lw += CTZ(csz); + return lw<7? lw : 7; +} diff --git a/src/core/tyarr.c b/src/core/tyarr.c index ec09a771..dfb11f2c 100644 --- a/src/core/tyarr.c +++ b/src/core/tyarr.c @@ -20,6 +20,14 @@ u8 arrTypeWidthLog[] = { [t_i32arr]=2, [t_i32slice]=2, [t_c32arr]=2, [t_c32slice]=2, [t_f64arr]=3, [t_f64slice]=3 }; +u8 arrTypeBitsLog[] = { + [t_bitarr]=0, + [t_i8arr ]=3, [t_i8slice ]=3, [t_c8arr ]=3, [t_c8slice ]=3, + [t_i16arr]=4, [t_i16slice]=4, [t_c16arr]=4, [t_c16slice]=4, + [t_i32arr]=5, [t_i32slice]=5, [t_c32arr]=5, [t_c32slice]=5, + [t_f64arr]=6, [t_f64slice]=6, + [t_harr ]=6, [t_hslice ]=6, [t_fillarr]=6,[t_fillslice]=6 +}; B m_i8(i8 x) { return m_i32(x); } B m_i16(i16 x) { return m_i32(x); } B m_c8(u8 x) { return m_c32(x); } B m_c16(u16 x) { return m_c32(x); } @@ -87,4 +95,4 @@ void tyarr_init() { Arr* emptySVec = arr_shVec(m_fillarrp(0)); fillarr_setFill(emptySVec, emptyCVec()); bi_emptySVec = taga(emptySVec); gc_add(bi_emptySVec); -} \ No newline at end of file +}