@@ -221,19 +221,14 @@ value_from_X(X p) -> T {
221221template <>
222222[[nodiscard]] auto
223223convert<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
239234template <>
@@ -305,9 +300,6 @@ template <>
305300[[nodiscard]] auto
306301convert<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
358343template <>
@@ -594,19 +579,12 @@ jtbcvt(J jt, C mode, array w) -> array {
594579
595580auto
596581jticvt (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
612590auto
0 commit comments