Skip to content

Commit c82d61a

Browse files
committed
Refactor couple transforms
1 parent 6d3f220 commit c82d61a

1 file changed

Lines changed: 20 additions & 20 deletions

File tree

jsrc/conversions.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -561,48 +561,48 @@ jtcvt(J jt, I t, A w) {
561561
A
562562
jtbcvt(J jt, C mode, A w) {
563563
FPREFIP;
564-
A y, z = w;
565564
if (!w) return 0;
565+
566+
auto const as_integer = [](auto const &v) { return *(I *)&v; };
567+
auto const isflag = [&](auto const &z) { return as_integer(z.im) == NANFLAG; };
568+
566569
// there may be values (especially b types) that were nominally CMPX but might actually be integers. Those were
567570
// stored with the real part being the actual integer value and the imaginary part as the special 'flag' value. We
568571
// handle those here. If all the imaginary parts were flags, we accept all the integer parts and change the type
569572
// to integer. If none of the imaginary parts were flags, we leave the input unchanged. If some were flags, we
570573
// convert the flagged values to float and keep the result as complex
574+
array result = w;
571575
if ((((AN(w) - 1) | (AT(w) & CMPX) - 1)) >= 0) { // not empty AND complex
572-
I allflag = 1, anyflag = 0;
573-
Z *wv = ZAV(w);
574-
DO(AN(w), I isflag = *(I *)&wv[i].im == NANFLAG; allflag &= isflag; anyflag |= isflag;)
575-
if (anyflag) {
576+
Z *wv = ZAV(w);
577+
auto flags = std::transform_reduce(wv, wv + AN(w), int64_t{}, std::plus{}, isflag);
578+
if (flags) {
576579
I ipok = SGNIF(jtinplace, JTINPLACEWX) & AC(w); // both sign bits set (<0) if inplaceable
577-
if (allflag) {
578-
if (ipok >= 0) GATV(z, INT, AN(w), AR(w), AS(w));
579-
I *zv = IAV(z); // output area
580-
DO(AN(w), zv[i] = *(I *)&wv[i].re;) // copy the results as integers
580+
if (flags == AN(w)) {
581+
if (ipok >= 0) GATV(result, INT, AN(w), AR(w), AS(w));
582+
std::transform(wv, wv + AN(w), IAV(result), [&](auto const &z) { return as_integer(z.re); });
581583
} else {
582-
if (ipok >= 0) GATV(z, CMPX, AN(w), AR(w), AS(w));
583-
Z *zv = ZAV(z); // output area
584-
DO(
585-
AN(w),
586-
if (*(I *)&wv[i].im == NANFLAG) {
587-
zv[i].re = (D) * (I *)&wv[i].re;
588-
zv[i].im = 0.0;
589-
} else { zv[i] = wv[i]; }) // copy floats, and converts any integers back to float
584+
if (ipok >= 0) GATV(result, CMPX, AN(w), AR(w), AS(w));
585+
std::transform(wv, wv + AN(w), ZAV(result), [&](auto const &z) -> Z {
586+
if (isflag(z)) return {.re = (D)as_integer(z.re), .im = 0.0};
587+
return z; // copy floats, and converts any integers back to float
588+
});
590589
}
591-
w = z; // this result is now eligible for further demotion
590+
w = result; // this result is now eligible for further demotion
592591
}
593592
}
594593
// for all numerics, try Boolean/int/float in order, stopping when we find one that holds the data
595594
if (mode & 1 || !(AT(w) & XNUM + RAT)) { // if we are not stopping at XNUM/RAT
596595
// To avoid a needless copy, suppress conversion to B01 if type is B01, to INT if type is INT, etc
597596
// set the NOFUZZ flag in jt to insist on an exact match so we won't lose precision
597+
array y;
598598
jtinplace = (J)((I)jt + JTNOFUZZ); // demand exact match
599-
z = !(mode & 14) && jtccvt(jtinplace, B01, w, &y) ? y
599+
result = !(mode & 14) && jtccvt(jtinplace, B01, w, &y) ? y
600600
: (y = w, AT(w) & INT || (!(mode & 12) && jtccvt(jtinplace, INT, w, &y))) ? y
601601
: (y = w, AT(w) & FL || (!(mode & 8) && jtccvt(jtinplace, FL, w, &y)))
602602
? y
603603
: w; // convert to enabled modes one by one, stopping when one works
604604
}
605-
RNE(z);
605+
RNE(result);
606606
} /* convert to lowest type. 0=mode: don't convert XNUM/RAT to other types */
607607

608608
A

0 commit comments

Comments
 (0)