Skip to content

Commit d1f28e8

Browse files
committed
Add specialisations for convert()
1 parent 5cb4ee7 commit d1f28e8

1 file changed

Lines changed: 78 additions & 64 deletions

File tree

jsrc/conversions.cpp

Lines changed: 78 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2323
template <typename T, typename V>
24-
[[nodiscard]] static constexpr auto
24+
[[nodiscard]] constexpr auto
2525
in_range(V value) -> bool {
2626
return std::numeric_limits<T>::min() <= value && value <= std::numeric_limits<T>::max();
2727
}
2828

2929
template <typename T, typename V>
30-
[[nodiscard]] static constexpr auto
30+
[[nodiscard]] constexpr auto
3131
in_range() -> bool {
3232
return in_range<T>(std::numeric_limits<V>::min()) && in_range<T>(std::numeric_limits<V>::max());
3333
}
3434

3535
template <typename From, typename To>
36-
[[nodiscard]] static auto
36+
[[nodiscard]] auto
3737
convert(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

4848
template <typename From, typename To, typename Transform>
49-
[[nodiscard]] static auto
49+
[[nodiscard]] auto
5050
convert(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

Comments
 (0)