@@ -21,19 +21,19 @@ extern "C" {
2121 ABS (v)) // used when v is known to be exact integer. It's close enough, maybe ULP too small on the high end
2222
2323template <typename T, typename V>
24- [[nodiscard]] static constexpr auto
24+ [[nodiscard]] constexpr auto
2525in_range(V value) -> bool {
2626 return std::numeric_limits<T>::min () <= value && value <= std::numeric_limits<T>::max ();
2727}
2828
2929template <typename T, typename V>
30- [[nodiscard]] static constexpr auto
30+ [[nodiscard]] constexpr auto
3131in_range () -> bool {
3232 return in_range<T>(std::numeric_limits<V>::min ()) && in_range<T>(std::numeric_limits<V>::max ());
3333}
3434
3535template <typename From, typename To>
36- [[nodiscard]] static auto
36+ [[nodiscard]] auto
3737convert (J jt, array w, void *yv) -> bool {
3838 From *v = reinterpret_cast <From *>(UAV (w));
3939 if constexpr (!in_range<To, From>()) {
@@ -46,15 +46,16 @@ convert(J jt, array w, void *yv) -> bool {
4646}
4747
4848template <typename From, typename To, typename Transform>
49- [[nodiscard]] static auto
49+ [[nodiscard]] auto
5050convert (J jt, array w, void *yv, Transform t) -> bool {
5151 From *v = reinterpret_cast <From*>(UAV (w));
5252 std::transform (v, v + AN (w), static_cast <To*>(yv), t);
5353 return 1 ;
5454}
5555
56- static B
57- jtBfromD (J jt, A w, void *yv, D fuzz) {
56+ template <>
57+ [[nodiscard]] auto
58+ convert<D, bool >(J jt, A w, void *yv, D fuzz) -> bool {
5859 auto n = AN (w);
5960 auto v = DAV (w);
6061 auto x = (B *)yv;
@@ -67,8 +68,9 @@ jtBfromD(J jt, A w, void *yv, D fuzz) {
6768 return 1 ;
6869}
6970
70- static B
71- jtIfromD (J jt, A w, void *yv, D fuzz) {
71+ template <>
72+ [[nodiscard]] auto
73+ convert<D, I>(J jt, A w, void *yv, D fuzz) -> bool {
7274 auto n = AN (w);
7375 auto v = DAV (w);
7476 auto x = (I *)yv;
@@ -91,8 +93,9 @@ jtIfromD(J jt, A w, void *yv, D fuzz) {
9193 return 1 ;
9294}
9395
94- static B
95- jtDfromZ (J jt, A w, void *yv, D fuzz) {
96+ template <>
97+ [[nodiscard]] auto
98+ convert<Z, D>(J jt, A w, void *yv, D fuzz) -> bool {
9699 auto const n = AN (w);
97100 auto const *v = ZAV (w);
98101 auto x = (D *)yv;
@@ -111,8 +114,9 @@ jtDfromZ(J jt, A w, void *yv, D fuzz) {
111114 return 1 ;
112115}
113116
114- static B
115- jtXfromB (J jt, A w, void *yv) {
117+ template <>
118+ [[nodiscard]] auto
119+ convert<bool , X>(J jt, A w, void *yv) -> bool {
116120 return convert<B, X>(jt,
117121 w,
118122 yv,
@@ -129,8 +133,9 @@ inplace_negate(T& u, int64_t n) {
129133 std::transform (u, u + n, u, [](auto v) { return -v; });
130134}
131135
132- static B
133- jtXfromI (J jt, A w, void *yv) {
136+ template <>
137+ [[nodiscard]] auto
138+ convert<I, X>(J jt, A w, void *yv) -> bool {
134139 I u[XIDIG];
135140 auto const v = AV (w);
136141 std::transform (v, v + AN (w), static_cast <X *>(yv), [&](auto c) {
@@ -191,13 +196,15 @@ jtxd1(J jt, D p, I mode) {
191196 EPILOG (z);
192197}
193198
194- static B
195- jtXfromD (J jt, A w, void *yv, I mode) {
199+ template <>
200+ [[nodiscard]] auto
201+ convert<D, X>(J jt, A w, void *yv, I mode) -> bool {
196202 return convert<D, X>(jt, w, yv, [=](auto v){ return jtxd1 (jt, v, mode); }) && !jt->jerr ;
197203}
198204
199- static B
200- jtBfromX (J jt, A w, void *yv) {
205+ template <>
206+ [[nodiscard]] auto
207+ convert<X, bool >(J jt, A w, void *yv) -> bool {
201208 auto v = XAV (w);
202209 auto x = (B *)yv;
203210 DO (AN (w), A q = v[i]; I e = AV (q)[0 ]; if ((AN (q) ^ 1 ) | (e & -2 )) return 0 ; x[i] = (B)e;);
@@ -212,8 +219,9 @@ value_from_X(X p) -> T {
212219 return std::accumulate (v, v + n, T{}, [](auto d, auto v) { return v + d * XBASE; });
213220}
214221
215- static B
216- jtIfromX (J jt, A w, void *yv) {
222+ template <>
223+ [[nodiscard]] auto
224+ convert<X, I>(J jt, A w, void *yv) -> bool {
217225 auto v = XAV (w);
218226 auto x = (I *)yv;
219227 auto n = AN (w);
@@ -228,8 +236,9 @@ jtIfromX(J jt, A w, void *yv) {
228236 return 1 ;
229237}
230238
231- static B
232- jtDfromX (J jt, A w, void *yv) {
239+ template <>
240+ [[nodiscard]] auto
241+ convert<X, D>(J jt, A w, void *yv) -> bool {
233242 auto const wv = XAV (w);
234243 std::transform (wv, wv + AN (w), static_cast <D *>(yv), [](auto p) {
235244 auto const c = AV (p)[AN (p)-1 ];
@@ -240,13 +249,15 @@ jtDfromX(J jt, A w, void *yv) {
240249 return 1 ;
241250}
242251
243- static B
244- jtQfromX (J jt, A w, void *yv) {
252+ template <>
253+ [[nodiscard]] auto
254+ convert<X, Q>(J jt, A w, void *yv) -> bool {
245255 return convert<X, Q>(jt, w, yv, [](auto v) -> Q { return {v, iv1}; });
246256}
247257
248- static B
249- jtQfromD (J jt, A w, void *yv, I mode) {
258+ template <>
259+ [[nodiscard]] auto
260+ convert<D, Q>(J jt, A w, void *yv, I mode) -> bool {
250261 B neg, recip;
251262 D c, d, t, *wv;
252263 I e, i, n, *v;
@@ -294,8 +305,9 @@ jtQfromD(J jt, A w, void *yv, I mode) {
294305 return !jt->jerr ;
295306}
296307
297- static B
298- jtDfromQ (J jt, A w, void *yv) {
308+ template <>
309+ [[nodiscard]] auto
310+ convert<Q, D>(J jt, A w, void *yv) -> bool {
299311 auto const xb = (D)XBASE;
300312 auto const wn = AN (w);
301313 auto const wv = QAV (w);
@@ -343,17 +355,19 @@ jtDfromQ(J jt, A w, void *yv) {
343355 return 1 ;
344356}
345357
346- static B
347- jtXfromQ (J jt, A w, void *yv) {
358+ template <>
359+ [[nodiscard]] auto
360+ convert<Q, X>(J jt, A w, void *yv) -> bool {
348361 auto v = QAV (w);
349362 auto x = (X *)yv;
350363 DQ (AN (w), if (!(jtequ (jt, iv1, v->d ))) return 0 ; *x++ = v->n ; ++v;);
351364 return !jt->jerr ;
352365}
353366
354367// Imaginary parts have already been cleared
355- static B
356- jtZfromD (J jt, A w, void *yv) {
368+ template <>
369+ [[nodiscard]] auto
370+ convert<D, Z>(J jt, A w, void *yv) -> bool {
357371 D *wv = DAV (w);
358372 Z *zv = static_cast <Z*>(yv);
359373 DQ (AN (w), zv++->re = *wv++;);
@@ -455,8 +469,8 @@ jtccvt(J jt, I tflagged, A w, A *y) {
455469 case CVCASE (INTX, B01X):
456470 std::copy_n (static_cast <B*>(wv), n, static_cast <I*>(yv));
457471 return 1 ;
458- case CVCASE (XNUMX, B01X): return jtXfromB (jt, w, yv);
459- case CVCASE (RATX, B01X): GATV (d, XNUM, n, r, s); return jtXfromB (jt, w, AV (d)) && jtQfromX (jt, d, yv);
472+ case CVCASE (XNUMX, B01X): return convert< bool , X> (jt, w, yv);
473+ case CVCASE (RATX, B01X): GATV (d, XNUM, n, r, s); return convert< bool , X> (jt, w, AV (d)) && convert<X, Q> (jt, d, yv);
460474 case CVCASE (FLX, B01X):
461475 std::copy_n (static_cast <B*>(wv), n, static_cast <D*>(yv));
462476 return 1 ;
@@ -467,8 +481,8 @@ jtccvt(J jt, I tflagged, A w, A *y) {
467481 }
468482 return 1 ;
469483 case CVCASE (B01X, INTX): return convert<I, bool >(jt, w, yv);
470- case CVCASE (XNUMX, INTX): return jtXfromI (jt, w, yv);
471- case CVCASE (RATX, INTX): GATV (d, XNUM, n, r, s); return jtXfromI (jt, w, AV (d)) && jtQfromX (jt, d, yv);
484+ case CVCASE (XNUMX, INTX): return convert<I, X> (jt, w, yv);
485+ case CVCASE (RATX, INTX): GATV (d, XNUM, n, r, s); return convert<I, X> (jt, w, AV (d)) && convert<X, Q> (jt, d, yv);
472486 case CVCASE (FLX, INTX):
473487 std::copy_n (static_cast <I*>(wv), n, static_cast <D*>(yv));
474488 return 1 ;
@@ -478,52 +492,52 @@ jtccvt(J jt, I tflagged, A w, A *y) {
478492 DQ (n, x++->re = (D)*v++;);
479493 }
480494 return 1 ;
481- case CVCASE (B01X, FLX): return jtBfromD (jt, w, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
482- case CVCASE (INTX, FLX): return jtIfromD (jt, w, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
495+ case CVCASE (B01X, FLX): return convert<D, bool > (jt, w, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
496+ case CVCASE (INTX, FLX): return convert<D, I> (jt, w, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
483497 case CVCASE (XNUMX, FLX):
484- return jtXfromD (jt, w, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
498+ return convert<D, X> (jt, w, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
485499 case CVCASE (RATX, FLX):
486- return jtQfromD (jt, w, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
487- case CVCASE (CMPXX, FLX): return jtZfromD (jt, w, yv);
500+ return convert<D, Q> (jt, w, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
501+ case CVCASE (CMPXX, FLX): return convert<D, Z> (jt, w, yv);
488502 case CVCASE (B01X, CMPXX):
489503 GATV (d, FL, n, r, s);
490- if (!(jtDfromZ (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
491- return jtBfromD (jt, d, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
504+ if (!(convert<Z, D> (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
505+ return convert<D, bool > (jt, d, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
492506 case CVCASE (INTX, CMPXX):
493507 GATV (d, FL, n, r, s);
494- if (!(jtDfromZ (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
495- return jtIfromD (jt, d, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
508+ if (!(convert<Z, D> (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
509+ return convert<D, I> (jt, d, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
496510 case CVCASE (XNUMX, CMPXX):
497511 GATV (d, FL, n, r, s);
498- if (!(jtDfromZ (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
499- return jtXfromD (jt, d, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
512+ if (!(convert<Z, D> (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
513+ return convert<D, X> (jt, d, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
500514 case CVCASE (RATX, CMPXX):
501515 GATV (d, FL, n, r, s);
502- if (!(jtDfromZ (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
503- return jtQfromD (jt, d, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
504- case CVCASE (FLX, CMPXX): return jtDfromZ (jt, w, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
505- case CVCASE (B01X, XNUMX): return jtBfromX (jt, w, yv);
506- case CVCASE (INTX, XNUMX): return jtIfromX (jt, w, yv);
507- case CVCASE (RATX, XNUMX): return jtQfromX (jt, w, yv);
508- case CVCASE (FLX, XNUMX): return jtDfromX (jt, w, yv);
516+ if (!(convert<Z, D> (jt, w, AV (d), (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ))) return 0 ;
517+ return convert<D, Q> (jt, d, yv, (jt->xmode & REPSGN (SGNIFNOT (tflagged, XCVTXNUMORIDEX))) | (tflagged >> XCVTXNUMCVX));
518+ case CVCASE (FLX, CMPXX): return convert<Z, D> (jt, w, yv, (I)jtinplace & JTNOFUZZ ? 0.0 : FUZZ);
519+ case CVCASE (B01X, XNUMX): return convert<X, bool > (jt, w, yv);
520+ case CVCASE (INTX, XNUMX): return convert<X, I> (jt, w, yv);
521+ case CVCASE (RATX, XNUMX): return convert<X, Q> (jt, w, yv);
522+ case CVCASE (FLX, XNUMX): return convert<X, D> (jt, w, yv);
509523 case CVCASE (CMPXX, XNUMX):
510524 GATV (d, FL, n, r, s);
511- if (!(jtDfromX (jt, w, AV (d)))) return 0 ;
512- return jtZfromD (jt, d, yv);
525+ if (!(convert<X, D> (jt, w, AV (d)))) return 0 ;
526+ return convert<D, Z> (jt, d, yv);
513527 case CVCASE (B01X, RATX):
514528 GATV (d, XNUM, n, r, s);
515- if (!(jtXfromQ (jt, w, AV (d)))) return 0 ;
516- return jtBfromX (jt, d, yv);
529+ if (!(convert<Q, X> (jt, w, AV (d)))) return 0 ;
530+ return convert<X, bool > (jt, d, yv);
517531 case CVCASE (INTX, RATX):
518532 GATV (d, XNUM, n, r, s);
519- if (!(jtXfromQ (jt, w, AV (d)))) return 0 ;
520- return jtIfromX (jt, d, yv);
521- case CVCASE (XNUMX, RATX): return jtXfromQ (jt, w, yv);
522- case CVCASE (FLX, RATX): return jtDfromQ (jt, w, yv);
533+ if (!(convert<Q, X> (jt, w, AV (d)))) return 0 ;
534+ return convert<X, I> (jt, d, yv);
535+ case CVCASE (XNUMX, RATX): return convert<Q, X> (jt, w, yv);
536+ case CVCASE (FLX, RATX): return convert<Q, D> (jt, w, yv);
523537 case CVCASE (CMPXX, RATX):
524538 GATV (d, FL, n, r, s);
525- if (!(jtDfromQ (jt, w, AV (d)))) return 0 ;
526- return jtZfromD (jt, d, yv);
539+ if (!(convert<Q, D> (jt, w, AV (d)))) return 0 ;
540+ return convert<D, Z> (jt, d, yv);
527541 default : ASSERT (0 , EVDOMAIN);
528542 }
529543}
0 commit comments