Skip to content

Commit ee1f07a

Browse files
committed
Use convert() instead of raw loops
1 parent ec8d8c3 commit ee1f07a

1 file changed

Lines changed: 33 additions & 55 deletions

File tree

jsrc/conversions.cpp

Lines changed: 33 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -221,19 +221,14 @@ value_from_X(X p) -> T {
221221
template <>
222222
[[nodiscard]] auto
223223
convert<X, I>(J jt, array w, void *yv) -> bool {
224-
auto *v = pointer_to_values<X>(w);
225-
auto *x = static_cast<I *>(yv);
226-
auto n = AN(w);
227-
X p = nullptr;
228-
X q;
229-
if ((p = jtxc(jt, IMAX)) == nullptr) return false;
230-
if ((q = jtxminus(jt, jtnegate(jt, p), jtxc(jt, 1L))) == nullptr) return false;
231-
for (int64_t i = 0; i < n; ++i) {
232-
auto *c = v[i];
233-
if (!(1 != jtxcompare(jt, q, c) && 1 != jtxcompare(jt, c, p))) return false;
234-
x[i] = value_from_X<int64_t>(c);
235-
}
236-
return 1;
224+
X p = jtxc(jt, IMAX);
225+
if (!p) return false;
226+
X q = jtxminus(jt, jtnegate(jt, p), jtxc(jt, 1L));
227+
if (!q) return false;
228+
return convert<X, I>(jt, w, yv, [&](auto c) -> std::optional<int64_t> {
229+
if (!(1 != jtxcompare(jt, q, c) && 1 != jtxcompare(jt, c, p))) return std::nullopt;
230+
return value_from_X<int64_t>(c);
231+
});
237232
}
238233

239234
template <>
@@ -305,9 +300,6 @@ template <>
305300
[[nodiscard]] auto
306301
convert<Q, D>(J jt, array w, void *yv) -> bool {
307302
auto const xb = static_cast<D>(XBASE);
308-
auto const wn = AN(w);
309-
auto *const wv = pointer_to_values<Q>(w);
310-
auto *const x = static_cast<D *>(yv);
311303
auto const nn = 308 / XBASEN;
312304

313305
// TODO: figure out nice algorithm for this
@@ -322,37 +314,30 @@ convert<Q, D>(J jt, array w, void *yv) -> bool {
322314
};
323315

324316
X x2 = nullptr;
325-
for (int64_t i = 0; i < wn; ++i) {
326-
auto *const p = wv[i].n;
317+
return convert<Q, D>(jt, w, yv, [&](auto nd) -> std::optional<D> {
318+
auto *const p = nd.n;
327319
auto const pn = AN(p);
328-
auto const k = 1 == pn ? pointer_to_values<int64_t>(p)[0] : 0;
329-
auto *const q = wv[i].d;
320+
auto const kk = 1 == pn ? pointer_to_values<int64_t>(p)[0] : 0;
321+
if (kk == XPINF) return inf;
322+
if (kk == XNINF) return infm;
323+
auto *const q = nd.d;
330324
auto const qn = AN(q);
331-
if (k == XPINF) {
332-
x[i] = inf;
333-
} else if (k == XNINF) {
334-
x[i] = infm;
335-
} else if (pn <= nn && qn <= nn) {
325+
if (pn <= nn && qn <= nn) {
336326
auto const n = add_digits(pn, pointer_to_values<int64_t>(p));
337327
auto const d = add_digits(qn, pointer_to_values<int64_t>(q));
338-
x[i] = n / d;
339-
} else {
340-
if (x2 == nullptr) {
341-
if ((x2 = jtxc(jt, 2L)) == nullptr) return false;
342-
}
343-
auto const k = 5 + qn;
344-
auto *c = jtxdiv(jt, jttake(jt, jtsc(jt, -(k + pn)), p), q, XMFLR);
345-
if (c == nullptr) return false;
346-
auto const cn = AN(c);
347-
auto const m = MIN(cn, 5);
348-
auto const r = cn - (m + k);
349-
auto *const v = pointer_to_values<int64_t>(c) + cn - m;
350-
auto const n = add_digits(m, v);
351-
auto d = std::pow(xb, std::abs(r));
352-
x[i] = 0 > r ? n / d : n * d;
328+
return n / d;
353329
}
354-
}
355-
return true;
330+
if (!x2 && !(x2 = jtxc(jt, 2L))) return std::nullopt;
331+
auto const k = 5 + qn;
332+
auto *c = jtxdiv(jt, jttake(jt, jtsc(jt, -(k + pn)), p), q, XMFLR);
333+
if (!c) return std::nullopt;
334+
auto const cn = AN(c);
335+
auto const m = MIN(cn, 5);
336+
auto const r = cn - (m + k);
337+
auto const n = add_digits(m, pointer_to_values<int64_t>(c) + cn - m);
338+
auto d = std::pow(xb, std::abs(r));
339+
return 0 > r ? n / d : n * d;
340+
});
356341
}
357342

358343
template <>
@@ -594,19 +579,12 @@ jtbcvt(J jt, C mode, array w) -> array {
594579

595580
auto
596581
jticvt(J jt, array w) -> array {
597-
auto const n = AN(w);
598-
auto const *v = pointer_to_values<double>(w);
599-
array z = nullptr;
600-
GATV(z, INT, n, AR(w), AS(w));
601-
auto *u = pointer_to_values<int64_t>(z);
602-
for (int64_t i = 0; i < n; ++i) {
603-
auto x = *v++;
604-
if (x < IMIN || FLIMAX <= x) {
605-
return w; // if conversion will fail, skip it
606-
}
607-
*u++ = static_cast<I>(x);
608-
}
609-
return z;
582+
array z = nullptr;
583+
GATV(z, INT, AN(w), AR(w), AS(w));
584+
return convert<double, int64_t>(
585+
jt, w, pointer_to_values<void>(z), [](auto x) { return value_if(IMIN <= x && x < FLIMAX, x); })
586+
? z
587+
: w; // if conversion will fail, skip it
610588
}
611589

612590
auto

0 commit comments

Comments
 (0)