xnd 0.2.0dev3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +42 -0
  3. data/Gemfile +3 -0
  4. data/History.md +0 -0
  5. data/README.md +7 -0
  6. data/Rakefile +135 -0
  7. data/ext/ruby_xnd/extconf.rb +70 -0
  8. data/ext/ruby_xnd/float_pack_unpack.c +277 -0
  9. data/ext/ruby_xnd/float_pack_unpack.h +39 -0
  10. data/ext/ruby_xnd/gc_guard.c +36 -0
  11. data/ext/ruby_xnd/gc_guard.h +12 -0
  12. data/ext/ruby_xnd/include/xnd.h +449 -0
  13. data/ext/ruby_xnd/lib/libxnd.a +0 -0
  14. data/ext/ruby_xnd/lib/libxnd.so +1 -0
  15. data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
  16. data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
  17. data/ext/ruby_xnd/memory_block_object.c +32 -0
  18. data/ext/ruby_xnd/memory_block_object.h +33 -0
  19. data/ext/ruby_xnd/ruby_xnd.c +1953 -0
  20. data/ext/ruby_xnd/ruby_xnd.h +61 -0
  21. data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
  22. data/ext/ruby_xnd/util.h +170 -0
  23. data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
  24. data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
  25. data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
  26. data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
  27. data/ext/ruby_xnd/xnd/Makefile.in +80 -0
  28. data/ext/ruby_xnd/xnd/README.rst +44 -0
  29. data/ext/ruby_xnd/xnd/config.guess +1530 -0
  30. data/ext/ruby_xnd/xnd/config.h.in +22 -0
  31. data/ext/ruby_xnd/xnd/config.sub +1782 -0
  32. data/ext/ruby_xnd/xnd/configure +4867 -0
  33. data/ext/ruby_xnd/xnd/configure.ac +164 -0
  34. data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
  35. data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
  36. data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
  37. data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
  38. data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
  39. data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
  40. data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
  41. data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
  42. data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
  43. data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
  44. data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
  45. data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
  46. data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
  47. data/ext/ruby_xnd/xnd/install-sh +527 -0
  48. data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
  49. data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
  50. data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
  51. data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
  52. data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
  53. data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
  54. data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
  55. data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
  56. data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
  57. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
  58. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
  59. data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
  60. data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
  61. data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
  62. data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
  63. data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
  64. data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
  65. data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
  66. data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
  67. data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
  68. data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
  69. data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
  70. data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
  71. data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
  72. data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
  73. data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
  74. data/ext/ruby_xnd/xnd/setup.py +303 -0
  75. data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
  76. data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
  77. data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
  78. data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
  79. data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
  80. data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
  81. data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
  82. data/lib/ruby_xnd.so +0 -0
  83. data/lib/xnd.rb +306 -0
  84. data/lib/xnd/monkeys.rb +29 -0
  85. data/lib/xnd/version.rb +6 -0
  86. data/spec/debug_spec.rb +9 -0
  87. data/spec/gc_guard_spec.rb +10 -0
  88. data/spec/leakcheck.rb +9 -0
  89. data/spec/spec_helper.rb +877 -0
  90. data/spec/type_inference_spec.rb +81 -0
  91. data/spec/xnd_spec.rb +2921 -0
  92. data/xnd.gemspec +47 -0
  93. metadata +215 -0
@@ -0,0 +1,1216 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #include <stdlib.h>
35
+ #include <stdint.h>
36
+ #include <inttypes.h>
37
+ #include <string.h>
38
+ #include <assert.h>
39
+ #include "ndtypes.h"
40
+ #include "xnd.h"
41
+ #include "contrib.h"
42
+
43
+
44
+ /*****************************************************************************/
45
+ /* Equality with strict type checking */
46
+ /*****************************************************************************/
47
+
48
+ int
49
+ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
50
+ {
51
+ const ndt_t * const t = x->type;
52
+ const ndt_t * const u = y->type;
53
+ int n;
54
+
55
+ assert(ndt_is_concrete(t) && ndt_is_concrete(u));
56
+
57
+ if (t->tag != u->tag) {
58
+ ndt_err_format(ctx, NDT_TypeError,
59
+ "mixed type comparisons are not implemented");
60
+ return -1;
61
+ }
62
+
63
+ if (xnd_is_na(x) || xnd_is_na(y)) {
64
+ return 0;
65
+ }
66
+
67
+ switch (t->tag) {
68
+ case FixedDim: {
69
+ int64_t i;
70
+
71
+ if (u->FixedDim.shape != t->FixedDim.shape) {
72
+ return 0;
73
+ }
74
+
75
+ for (i = 0; i < t->FixedDim.shape; i++) {
76
+ const xnd_t xnext = xnd_fixed_dim_next(x, i);
77
+ const xnd_t ynext = xnd_fixed_dim_next(y, i);
78
+ n = xnd_strict_equal(&xnext, &ynext, ctx);
79
+ if (n <= 0) return n;
80
+ }
81
+
82
+ return 1;
83
+ }
84
+
85
+ case VarDim: {
86
+ int64_t xstart, xstep, xshape;
87
+ int64_t ystart, ystep, yshape;
88
+ int64_t i;
89
+
90
+ xshape = ndt_var_indices(&xstart, &xstep, t, x->index, ctx);
91
+ if (xshape < 0) {
92
+ return -1;
93
+ }
94
+
95
+ yshape = ndt_var_indices(&ystart, &ystep, u, y->index, ctx);
96
+ if (yshape < 0) {
97
+ return -1;
98
+ }
99
+
100
+ if (yshape != xshape) {
101
+ return 0;
102
+ }
103
+
104
+ for (i = 0; i < xshape; i++) {
105
+ const xnd_t xnext = xnd_var_dim_next(x, xstart, xstep, i);
106
+ const xnd_t ynext = xnd_var_dim_next(y, ystart, ystep, i);
107
+ n = xnd_strict_equal(&xnext, &ynext, ctx);
108
+ if (n <= 0) return n;
109
+ }
110
+
111
+ return 1;
112
+ }
113
+
114
+ case Tuple: {
115
+ if (u->Tuple.shape != t->Tuple.shape) {
116
+ return 0;
117
+ }
118
+
119
+ for (int64_t i = 0; i < t->Tuple.shape; i++) {
120
+ const xnd_t xnext = xnd_tuple_next(x, i, ctx);
121
+ if (xnext.ptr == NULL) {
122
+ return -1;
123
+ }
124
+
125
+ const xnd_t ynext = xnd_tuple_next(y, i, ctx);
126
+ if (ynext.ptr == NULL) {
127
+ return -1;
128
+ }
129
+
130
+ n = xnd_strict_equal(&xnext, &ynext, ctx);
131
+ if (n <= 0) return n;
132
+ }
133
+
134
+ return 1;
135
+ }
136
+
137
+ case Record: {
138
+ if (u->Record.shape != t->Record.shape) {
139
+ return 0;
140
+ }
141
+
142
+ for (int64_t i = 0; i < t->Record.shape; i++) {
143
+ if (strcmp(t->Record.names[i], u->Record.names[i]) != 0) {
144
+ return 0;
145
+ }
146
+
147
+ const xnd_t xnext = xnd_record_next(x, i, ctx);
148
+ if (xnext.ptr == NULL) {
149
+ return -1;
150
+ }
151
+
152
+ const xnd_t ynext = xnd_record_next(y, i, ctx);
153
+ if (ynext.ptr == NULL) {
154
+ return -1;
155
+ }
156
+
157
+ n = xnd_strict_equal(&xnext, &ynext, ctx);
158
+ if (n <= 0) return n;
159
+ }
160
+
161
+ return 1;
162
+ }
163
+
164
+ case Ref: {
165
+ const xnd_t xnext = xnd_ref_next(x, ctx);
166
+ if (xnext.ptr == NULL) {
167
+ return -1;
168
+ }
169
+
170
+ const xnd_t ynext = xnd_ref_next(y, ctx);
171
+ if (ynext.ptr == NULL) {
172
+ return -1;
173
+ }
174
+
175
+ return xnd_strict_equal(&xnext, &ynext, ctx);
176
+ }
177
+
178
+ case Constr: {
179
+ if (strcmp(t->Constr.name, u->Constr.name) != 0) {
180
+ return 0;
181
+ }
182
+
183
+ const xnd_t xnext = xnd_constr_next(x, ctx);
184
+ if (xnext.ptr == NULL) {
185
+ return -1;
186
+ }
187
+
188
+ const xnd_t ynext = xnd_constr_next(y, ctx);
189
+ if (ynext.ptr == NULL) {
190
+ return -1;
191
+ }
192
+
193
+ return xnd_strict_equal(&xnext, &ynext, ctx);
194
+ }
195
+
196
+ case Nominal: {
197
+ if (strcmp(t->Nominal.name, u->Nominal.name) != 0) {
198
+ return 0;
199
+ }
200
+
201
+ const xnd_t xnext = xnd_nominal_next(x, ctx);
202
+ if (xnext.ptr == NULL) {
203
+ return -1;
204
+ }
205
+
206
+ const xnd_t ynext = xnd_nominal_next(y, ctx);
207
+ if (ynext.ptr == NULL) {
208
+ return -1;
209
+ }
210
+
211
+ return xnd_strict_equal(&xnext, &ynext, ctx);
212
+ }
213
+
214
+ case Categorical: {
215
+ int64_t i, k;
216
+
217
+ if (!ndt_equal(t, u)) {
218
+ return 0;
219
+ }
220
+
221
+ UNPACK_SINGLE(i, x->ptr, int64_t, t->flags);
222
+ UNPACK_SINGLE(k, y->ptr, int64_t, u->flags);
223
+
224
+ if (t->Categorical.types[i].tag == ValNA) {
225
+ return 0;
226
+ }
227
+
228
+ return i == k;
229
+ }
230
+
231
+ case Char: {
232
+ ndt_err_format(ctx, NDT_NotImplementedError, "char not implemented");
233
+ return -1;
234
+ }
235
+
236
+ case Bool: {
237
+ bool a, b;
238
+ UNPACK_SINGLE(a, x->ptr, bool, t->flags);
239
+ UNPACK_SINGLE(b, y->ptr, bool, u->flags);
240
+ return a == b;
241
+ }
242
+
243
+ case Int8: {
244
+ int8_t a, b;
245
+ UNPACK_SINGLE(a, x->ptr, int8_t, t->flags);
246
+ UNPACK_SINGLE(b, y->ptr, int8_t, u->flags);
247
+ return a == b;
248
+ }
249
+
250
+ case Int16: {
251
+ int16_t a, b;
252
+ UNPACK_SINGLE(a, x->ptr, int16_t, t->flags);
253
+ UNPACK_SINGLE(b, y->ptr, int16_t, u->flags);
254
+ return a == b;
255
+ }
256
+
257
+ case Int32: {
258
+ int32_t a, b;
259
+ UNPACK_SINGLE(a, x->ptr, int32_t, t->flags);
260
+ UNPACK_SINGLE(b, y->ptr, int32_t, u->flags);
261
+ return a == b;
262
+ }
263
+
264
+ case Int64: {
265
+ int64_t a, b;
266
+ UNPACK_SINGLE(a, x->ptr, int64_t, t->flags);
267
+ UNPACK_SINGLE(b, y->ptr, int64_t, u->flags);
268
+ return a == b;
269
+ }
270
+
271
+ case Uint8: {
272
+ uint8_t a, b;
273
+ UNPACK_SINGLE(a, x->ptr, uint8_t, t->flags);
274
+ UNPACK_SINGLE(b, y->ptr, uint8_t, u->flags);
275
+ return a == b;
276
+ }
277
+
278
+ case Uint16: {
279
+ uint16_t a, b;
280
+ UNPACK_SINGLE(a, x->ptr, uint16_t, t->flags);
281
+ UNPACK_SINGLE(b, y->ptr, uint16_t, u->flags);
282
+ return a == b;
283
+ }
284
+
285
+ case Uint32: {
286
+ uint32_t a, b;
287
+ UNPACK_SINGLE(a, x->ptr, uint32_t, t->flags);
288
+ UNPACK_SINGLE(b, y->ptr, uint32_t, u->flags);
289
+ return a == b;
290
+ }
291
+
292
+ case Uint64: {
293
+ uint64_t a, b;
294
+ UNPACK_SINGLE(a, x->ptr, uint64_t, t->flags);
295
+ UNPACK_SINGLE(b, y->ptr, uint64_t, u->flags);
296
+ return a == b;
297
+ }
298
+
299
+ case Float16: {
300
+ double a = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
301
+ double b = xnd_float_unpack2((unsigned char *)y->ptr, le(u->flags));
302
+ return a == b;
303
+ }
304
+
305
+ case Float32: {
306
+ double a = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
307
+ double b = xnd_float_unpack4((unsigned char *)y->ptr, le(u->flags));
308
+ return a == b;
309
+ }
310
+
311
+ case Float64: {
312
+ double a = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
313
+ double b = xnd_float_unpack8((unsigned char *)y->ptr, le(u->flags));
314
+ return a == b;
315
+ }
316
+
317
+ case Complex32: {
318
+ double a_real, a_imag;
319
+ double b_real, b_imag;
320
+
321
+ a_real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
322
+ a_imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
323
+
324
+ b_real = xnd_float_unpack2((unsigned char *)y->ptr, le(u->flags));
325
+ b_imag = xnd_float_unpack2((unsigned char *)(y->ptr+2), le(u->flags));
326
+
327
+ return a_real == b_real && a_imag == b_imag;
328
+ }
329
+
330
+ case Complex64: {
331
+ double a_real, a_imag;
332
+ double b_real, b_imag;
333
+
334
+ a_real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
335
+ a_imag = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
336
+
337
+ b_real = xnd_float_unpack4((unsigned char *)y->ptr, le(u->flags));
338
+ b_imag = xnd_float_unpack4((unsigned char *)(y->ptr+4), le(u->flags));
339
+
340
+ return a_real == b_real && a_imag == b_imag;
341
+ }
342
+
343
+ case Complex128: {
344
+ double a_real, a_imag;
345
+ double b_real, b_imag;
346
+
347
+ a_real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
348
+ a_imag = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
349
+
350
+ b_real = xnd_float_unpack8((unsigned char *)y->ptr, le(u->flags));
351
+ b_imag = xnd_float_unpack8((unsigned char *)(y->ptr+8), le(u->flags));
352
+
353
+ return a_real == b_real && a_imag == b_imag;
354
+ }
355
+
356
+ case FixedString: {
357
+ if (t->FixedString.size != u->FixedString.size ||
358
+ t->FixedString.encoding != u->FixedString.encoding ||
359
+ t->datasize != u->datasize) {
360
+ return 0;
361
+ }
362
+ return memcmp(x->ptr, y->ptr, (size_t)t->datasize) == 0;
363
+ }
364
+
365
+ case FixedBytes: {
366
+ if (t->FixedBytes.size != u->FixedBytes.size ||
367
+ t->datasize != u->datasize) {
368
+ return 0;
369
+ }
370
+ return memcmp(x->ptr, y->ptr, (size_t)t->datasize) == 0;
371
+ }
372
+
373
+ case String: {
374
+ const char *a = XND_POINTER_DATA(x->ptr);
375
+ const char *b = XND_POINTER_DATA(y->ptr);
376
+ return strcmp(a, b) == 0;
377
+ }
378
+
379
+ case Bytes: {
380
+ char *a, *b;
381
+ int64_t asize, bsize;
382
+
383
+ asize = XND_BYTES_SIZE(x->ptr);
384
+ bsize = XND_BYTES_SIZE(y->ptr);
385
+
386
+ a = (char *)XND_BYTES_DATA(x->ptr);
387
+ b = (char *)XND_BYTES_DATA(y->ptr);
388
+
389
+ if (asize != bsize) {
390
+ return 0;
391
+ }
392
+
393
+ return memcmp(a, b, (size_t)asize) == 0;
394
+ }
395
+
396
+ /* NOT REACHED: xnd types must be concrete. */
397
+ case Module: case Function:
398
+ case AnyKind: case SymbolicDim: case EllipsisDim: case Typevar:
399
+ case ScalarKind: case SignedKind: case UnsignedKind: case FloatKind:
400
+ case ComplexKind: case FixedStringKind: case FixedBytesKind:
401
+ ndt_err_format(ctx, NDT_RuntimeError, "unexpected abstract type");
402
+ return -1;
403
+ }
404
+
405
+ /* NOT REACHED: tags should be exhaustive */
406
+ ndt_err_format(ctx, NDT_RuntimeError, "invalid type tag");
407
+ return -1;
408
+ }
409
+
410
+
411
+ /*****************************************************************************/
412
+ /* Equality with exact casts */
413
+ /*****************************************************************************/
414
+
415
+ /* Skip all ref chains. */
416
+ static int
417
+ equal_ref(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
418
+ {
419
+ const ndt_t *t = x->type;
420
+ const ndt_t *u = y->type;
421
+ xnd_t xnext, ynext;
422
+
423
+ while (t->tag == Ref) {
424
+ xnext = xnd_ref_next(x, ctx);
425
+ if (xnext.ptr == NULL) {
426
+ return -1;
427
+ }
428
+ x = &xnext;
429
+ t = x->type;
430
+ }
431
+
432
+ while (u->tag == Ref) {
433
+ ynext = xnd_ref_next(y, ctx);
434
+ if (ynext.ptr == NULL) {
435
+ return -1;
436
+ }
437
+ y = &ynext;
438
+ u = y->type;
439
+ }
440
+
441
+ return xnd_equal(x, y, ctx);
442
+ }
443
+
444
+ static int
445
+ equal_int64(const int64_t a, const xnd_t * const x)
446
+ {
447
+ const ndt_t * const t = x->type;
448
+
449
+ switch (t->tag) {
450
+ case Int8: {
451
+ int8_t b;
452
+ UNPACK_SINGLE(b, x->ptr, int8_t, t->flags);
453
+ return a == (int64_t)b;
454
+ }
455
+
456
+ case Int16: {
457
+ int16_t b;
458
+ UNPACK_SINGLE(b, x->ptr, int16_t, t->flags);
459
+ return a == (int64_t)b;
460
+ }
461
+
462
+ case Int32: {
463
+ int32_t b;
464
+ UNPACK_SINGLE(b, x->ptr, int32_t, t->flags);
465
+ return a == (int64_t)b;
466
+ }
467
+
468
+ case Int64: {
469
+ int64_t b;
470
+ UNPACK_SINGLE(b, x->ptr, int64_t, t->flags);
471
+ return a == b;
472
+ }
473
+
474
+ case Uint8: {
475
+ uint8_t b;
476
+ UNPACK_SINGLE(b, x->ptr, uint8_t, t->flags);
477
+ return a >= 0 ? (uint64_t)a == (uint64_t)b : 0;
478
+ }
479
+
480
+ case Uint16: {
481
+ uint16_t b;
482
+ UNPACK_SINGLE(b, x->ptr, uint16_t, t->flags);
483
+ return a >= 0 ? (uint64_t)a == (uint64_t)b : 0;
484
+ }
485
+
486
+ case Uint32: {
487
+ uint32_t b;
488
+ UNPACK_SINGLE(b, x->ptr, uint32_t, t->flags);
489
+ return a >= 0 ? (uint64_t)a == (uint64_t)b : 0;
490
+ }
491
+
492
+ case Uint64: {
493
+ uint64_t b;
494
+ UNPACK_SINGLE(b, x->ptr, uint64_t, t->flags);
495
+ return a >= 0 ? (uint64_t)a == b : 0;
496
+ }
497
+
498
+ case Float16: {
499
+ double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
500
+ return llabs(a) <= 4503599627370496LL ? (double)a == b : 0;
501
+ }
502
+
503
+ case Float32: {
504
+ double b = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
505
+ return llabs(a) <= 4503599627370496LL ? (double)a == b : 0;
506
+ }
507
+
508
+ case Float64: {
509
+ double b = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
510
+ return llabs(a) <= 4503599627370496LL ? (double)a == b : 0;
511
+ }
512
+
513
+ case Complex32: {
514
+ double real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
515
+ double imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
516
+
517
+ if (imag == 0.0 && llabs(a) <= 4503599627370496LL) {
518
+ return (double)a == real;
519
+ }
520
+
521
+ return 0;
522
+ }
523
+
524
+ case Complex64: {
525
+ double real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
526
+ double imag = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
527
+
528
+ if (imag == 0.0 && llabs(a) <= 4503599627370496LL) {
529
+ return (double)a == real;
530
+ }
531
+
532
+ return 0;
533
+ }
534
+
535
+ case Complex128: {
536
+ double real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
537
+ double imag = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
538
+
539
+ if (imag == 0.0 && llabs(a) <= 4503599627370496LL) {
540
+ return (double)a == real;
541
+ }
542
+
543
+ return 0;
544
+ }
545
+ default:
546
+ return 0;
547
+ }
548
+ }
549
+
550
+ static int
551
+ equal_uint64(const uint64_t a, const xnd_t * const x)
552
+ {
553
+ const ndt_t * const t = x->type;
554
+
555
+ switch (t->tag) {
556
+ case Int8: {
557
+ int8_t b;
558
+ UNPACK_SINGLE(b, x->ptr, int8_t, t->flags);
559
+ return b >= 0 ? a == (uint64_t)b : 0;
560
+ }
561
+
562
+ case Int16: {
563
+ int16_t b;
564
+ UNPACK_SINGLE(b, x->ptr, int16_t, t->flags);
565
+ return b >= 0 ? a == (uint64_t)b : 0;
566
+ }
567
+
568
+ case Int32: {
569
+ int32_t b;
570
+ UNPACK_SINGLE(b, x->ptr, int32_t, t->flags);
571
+ return b >= 0 ? a == (uint64_t)b : 0;
572
+ }
573
+
574
+ case Int64: {
575
+ int64_t b;
576
+ UNPACK_SINGLE(b, x->ptr, int64_t, t->flags);
577
+ return b >= 0 ? a == (uint64_t)b : 0;
578
+ }
579
+
580
+ case Uint8: {
581
+ uint8_t b;
582
+ UNPACK_SINGLE(b, x->ptr, uint8_t, t->flags);
583
+ return a == (uint64_t)b;
584
+ }
585
+
586
+ case Uint16: {
587
+ uint16_t b;
588
+ UNPACK_SINGLE(b, x->ptr, uint16_t, t->flags);
589
+ return a == (uint64_t)b;
590
+ }
591
+
592
+ case Uint32: {
593
+ uint32_t b;
594
+ UNPACK_SINGLE(b, x->ptr, uint32_t, t->flags);
595
+ return a == (uint64_t)b;
596
+ }
597
+
598
+ case Uint64: {
599
+ uint64_t b;
600
+ UNPACK_SINGLE(b, x->ptr, uint64_t, t->flags);
601
+ return a == b;
602
+ }
603
+
604
+ case Float16: {
605
+ double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
606
+ return a <= 4503599627370496ULL ? (double)a == b : 0;
607
+ }
608
+
609
+ case Float32: {
610
+ double b = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
611
+ return a <= 4503599627370496ULL ? (double)a == b : 0;
612
+ }
613
+
614
+ case Float64: {
615
+ double b = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
616
+ return a <= 4503599627370496ULL ? (double)a == b : 0;
617
+ }
618
+
619
+ case Complex32: {
620
+ double real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
621
+ double imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
622
+
623
+ if (imag == 0.0 && a <= 4503599627370496ULL) {
624
+ return (double)a == real;
625
+ }
626
+
627
+ return 0;
628
+ }
629
+
630
+ case Complex64: {
631
+ double real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
632
+ double imag = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
633
+
634
+ if (imag == 0.0 && a <= 4503599627370496ULL) {
635
+ return (double)a == real;
636
+ }
637
+
638
+ return 0;
639
+ }
640
+
641
+ case Complex128: {
642
+ double real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
643
+ double imag = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
644
+
645
+ if (imag == 0.0 && a <= 4503599627370496ULL) {
646
+ return (double)a == real;
647
+ }
648
+
649
+ return 0;
650
+ }
651
+ default:
652
+ return 0;
653
+ }
654
+ }
655
+
656
+ static int
657
+ equal_float64(const double a, const xnd_t * const x)
658
+ {
659
+ const ndt_t * const t = x->type;
660
+
661
+ switch (t->tag) {
662
+ case Int8: {
663
+ int8_t b;
664
+ UNPACK_SINGLE(b, x->ptr, int8_t, t->flags);
665
+ return a == (double)b;
666
+ }
667
+
668
+ case Int16: {
669
+ int16_t b;
670
+ UNPACK_SINGLE(b, x->ptr, int16_t, t->flags);
671
+ return a == (double)b;
672
+ }
673
+
674
+ case Int32: {
675
+ int32_t b;
676
+ UNPACK_SINGLE(b, x->ptr, int32_t, t->flags);
677
+ return a == (double)b;
678
+ }
679
+
680
+ case Int64: {
681
+ int64_t b;
682
+ UNPACK_SINGLE(b, x->ptr, int64_t, t->flags);
683
+ return llabs(b) <= 4503599627370496LL ? a == (double)b : 0;
684
+ }
685
+
686
+ case Uint8: {
687
+ uint8_t b;
688
+ UNPACK_SINGLE(b, x->ptr, uint8_t, t->flags);
689
+ return a == (double)b;
690
+ }
691
+
692
+ case Uint16: {
693
+ uint16_t b;
694
+ UNPACK_SINGLE(b, x->ptr, uint16_t, t->flags);
695
+ return a == (double)b;
696
+ }
697
+
698
+ case Uint32: {
699
+ uint32_t b;
700
+ UNPACK_SINGLE(b, x->ptr, uint32_t, t->flags);
701
+ return a == (double)b;
702
+ }
703
+
704
+ case Uint64: {
705
+ uint64_t b;
706
+ UNPACK_SINGLE(b, x->ptr, uint64_t, t->flags);
707
+ return b <= 4503599627370496ULL ? a == (double)b : 0;
708
+ }
709
+
710
+ case Float16: {
711
+ double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
712
+ return a == b;
713
+ }
714
+
715
+ case Float32: {
716
+ double b = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
717
+ return a == b;
718
+ }
719
+
720
+ case Float64: {
721
+ double b = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
722
+ return a == b;
723
+ }
724
+
725
+ case Complex32: {
726
+ double real, imag;
727
+
728
+ real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
729
+ imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
730
+
731
+ if (imag == 0.0) {
732
+ return a == real;
733
+ }
734
+
735
+ return 0;
736
+ }
737
+
738
+ case Complex64: {
739
+ double real, imag;
740
+
741
+ real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
742
+ imag = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
743
+
744
+ if (imag == 0.0) {
745
+ return a == real;
746
+ }
747
+
748
+ return 0;
749
+ }
750
+
751
+ case Complex128: {
752
+ double real, imag;
753
+
754
+ real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
755
+ imag = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
756
+
757
+ if (imag == 0.0) {
758
+ return a == real;
759
+ }
760
+
761
+ return 0;
762
+ }
763
+ default:
764
+ return 0;
765
+ }
766
+ }
767
+
768
+ static int
769
+ equal_complex128(const double real, const double imag, const xnd_t * const x)
770
+ {
771
+ const ndt_t * const t = x->type;
772
+
773
+ switch (t->tag) {
774
+ case Int8: {
775
+ int8_t b;
776
+ UNPACK_SINGLE(b, x->ptr, int8_t, t->flags);
777
+ return imag == 0.0 ? real == (double)b : 0;
778
+ }
779
+
780
+ case Int16: {
781
+ int16_t b;
782
+ UNPACK_SINGLE(b, x->ptr, int16_t, t->flags);
783
+ return imag == 0.0 ? real == (double)b : 0;
784
+ }
785
+
786
+ case Int32: {
787
+ int32_t b;
788
+ UNPACK_SINGLE(b, x->ptr, int32_t, t->flags);
789
+ return imag == 0.0 ? real == (double)b : 0;
790
+ }
791
+
792
+ case Int64: {
793
+ int64_t b;
794
+ UNPACK_SINGLE(b, x->ptr, int64_t, t->flags);
795
+ return imag == 0.0 && llabs(b) <= 4503599627370496LL ? real == (double)b : 0;
796
+ }
797
+
798
+ case Uint8: {
799
+ uint8_t b;
800
+ UNPACK_SINGLE(b, x->ptr, uint8_t, t->flags);
801
+ return imag == 0.0 ? real == (double)b : 0;
802
+ }
803
+
804
+ case Uint16: {
805
+ uint16_t b;
806
+ UNPACK_SINGLE(b, x->ptr, uint16_t, t->flags);
807
+ return imag == 0.0 ? real == (double)b : 0;
808
+ }
809
+
810
+ case Uint32: {
811
+ uint32_t b;
812
+ UNPACK_SINGLE(b, x->ptr, uint32_t, t->flags);
813
+ return imag == 0.0 ? real == (double)b : 0;
814
+ }
815
+
816
+ case Uint64: {
817
+ uint64_t b;
818
+ UNPACK_SINGLE(b, x->ptr, uint64_t, t->flags);
819
+ return b <= 4503599627370496ULL ? real == (double)b : 0;
820
+ }
821
+
822
+ case Float16: {
823
+ double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
824
+ return imag == 0.0 && real == b;
825
+ }
826
+
827
+ case Float32: {
828
+ double b = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
829
+ return imag == 0.0 && real == b;
830
+ }
831
+
832
+ case Float64: {
833
+ double b = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
834
+ return imag == 0.0 && real == b;
835
+ }
836
+
837
+ case Complex32: {
838
+ double a = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
839
+ double b = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
840
+ return real == a && imag == b;
841
+ }
842
+
843
+ case Complex64: {
844
+ double a = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
845
+ double b = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
846
+ return real == a && imag == b;
847
+ }
848
+
849
+ case Complex128: {
850
+ double a = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
851
+ double b = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
852
+ return real == a && imag == b;
853
+ }
854
+ default:
855
+ return 0;
856
+ }
857
+ }
858
+
859
+ int
860
+ xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
861
+ {
862
+ const ndt_t * const t = x->type;
863
+ const ndt_t * const u = y->type;
864
+ int n;
865
+
866
+ if (xnd_is_na(x) || xnd_is_na(y)) {
867
+ return 0;
868
+ }
869
+
870
+ if (t->tag == Ref || u->tag == Ref) {
871
+ return equal_ref(x, y, ctx);
872
+ }
873
+
874
+ switch (t->tag) {
875
+ case FixedDim: {
876
+ int64_t i;
877
+
878
+ if (u->tag != FixedDim || u->FixedDim.shape != t->FixedDim.shape) {
879
+ return 0;
880
+ }
881
+
882
+ for (i = 0; i < t->FixedDim.shape; i++) {
883
+ const xnd_t xnext = xnd_fixed_dim_next(x, i);
884
+ const xnd_t ynext = xnd_fixed_dim_next(y, i);
885
+ n = xnd_equal(&xnext, &ynext, ctx);
886
+ if (n <= 0) return n;
887
+ }
888
+
889
+ return 1;
890
+ }
891
+
892
+ case VarDim: {
893
+ int64_t xstart, xstep, xshape;
894
+ int64_t ystart, ystep, yshape;
895
+ int64_t i;
896
+
897
+ if (u->tag != VarDim) {
898
+ return 0;
899
+ }
900
+
901
+ xshape = ndt_var_indices(&xstart, &xstep, t, x->index, ctx);
902
+ if (xshape < 0) {
903
+ return -1;
904
+ }
905
+
906
+ yshape = ndt_var_indices(&ystart, &ystep, u, y->index, ctx);
907
+ if (yshape < 0) {
908
+ return -1;
909
+ }
910
+
911
+ if (yshape != xshape) {
912
+ return 0;
913
+ }
914
+
915
+ for (i = 0; i < xshape; i++) {
916
+ const xnd_t xnext = xnd_var_dim_next(x, xstart, xstep, i);
917
+ const xnd_t ynext = xnd_var_dim_next(y, ystart, ystep, i);
918
+ n = xnd_equal(&xnext, &ynext, ctx);
919
+ if (n <= 0) return n;
920
+ }
921
+
922
+ return 1;
923
+ }
924
+
925
+ case Tuple: {
926
+ if (u->tag != Tuple || u->Tuple.shape != t->Tuple.shape) {
927
+ return 0;
928
+ }
929
+
930
+ for (int64_t i = 0; i < t->Tuple.shape; i++) {
931
+ const xnd_t xnext = xnd_tuple_next(x, i, ctx);
932
+ if (xnext.ptr == NULL) {
933
+ return -1;
934
+ }
935
+
936
+ const xnd_t ynext = xnd_tuple_next(y, i, ctx);
937
+ if (ynext.ptr == NULL) {
938
+ return -1;
939
+ }
940
+
941
+ n = xnd_equal(&xnext, &ynext, ctx);
942
+ if (n <= 0) return n;
943
+ }
944
+
945
+ return 1;
946
+ }
947
+
948
+ case Record: {
949
+ if (u->tag != Record || u->Record.shape != t->Record.shape) {
950
+ return 0;
951
+ }
952
+
953
+ for (int64_t i = 0; i < t->Record.shape; i++) {
954
+ if (strcmp(t->Record.names[i], u->Record.names[i]) != 0) {
955
+ return 0;
956
+ }
957
+
958
+ const xnd_t xnext = xnd_record_next(x, i, ctx);
959
+ if (xnext.ptr == NULL) {
960
+ return -1;
961
+ }
962
+
963
+ const xnd_t ynext = xnd_record_next(y, i, ctx);
964
+ if (ynext.ptr == NULL) {
965
+ return -1;
966
+ }
967
+
968
+ n = xnd_equal(&xnext, &ynext, ctx);
969
+ if (n <= 0) return n;
970
+ }
971
+
972
+ return 1;
973
+ }
974
+
975
+ case Constr: {
976
+ if (u->tag != Constr || strcmp(u->Constr.name, t->Constr.name) != 0) {
977
+ return 0;
978
+ }
979
+
980
+ const xnd_t xnext = xnd_constr_next(x, ctx);
981
+ if (xnext.ptr == NULL) {
982
+ return -1;
983
+ }
984
+
985
+ const xnd_t ynext = xnd_constr_next(y, ctx);
986
+ if (ynext.ptr == NULL) {
987
+ return -1;
988
+ }
989
+
990
+ return xnd_equal(&xnext, &ynext, ctx);
991
+ }
992
+
993
+ case Nominal: {
994
+ if (u->tag != Nominal) {
995
+ return 0;
996
+ }
997
+
998
+ if (strcmp(t->Nominal.name, u->Nominal.name) != 0) {
999
+ return 0;
1000
+ }
1001
+
1002
+ const xnd_t xnext = xnd_nominal_next(x, ctx);
1003
+ if (xnext.ptr == NULL) {
1004
+ return -1;
1005
+ }
1006
+
1007
+ const xnd_t ynext = xnd_nominal_next(y, ctx);
1008
+ if (ynext.ptr == NULL) {
1009
+ return -1;
1010
+ }
1011
+
1012
+ return xnd_equal(&xnext, &ynext, ctx);
1013
+ }
1014
+
1015
+ case Categorical: {
1016
+ int64_t i, k;
1017
+
1018
+ if (!ndt_equal(t, u)) {
1019
+ return 0;
1020
+ }
1021
+
1022
+ UNPACK_SINGLE(i, x->ptr, int64_t, t->flags);
1023
+ UNPACK_SINGLE(k, y->ptr, int64_t, u->flags);
1024
+
1025
+ if (t->Categorical.types[i].tag == ValNA) {
1026
+ return 0;
1027
+ }
1028
+
1029
+ return i == k;
1030
+ }
1031
+
1032
+ case Char: {
1033
+ ndt_err_format(ctx, NDT_NotImplementedError, "char not implemented");
1034
+ return -1;
1035
+ }
1036
+
1037
+ case Bool: {
1038
+ bool a, b;
1039
+
1040
+ if (u->tag != Bool) {
1041
+ return 0;
1042
+ }
1043
+
1044
+ UNPACK_SINGLE(a, x->ptr, bool, t->flags);
1045
+ UNPACK_SINGLE(b, y->ptr, bool, u->flags);
1046
+ return a == b;
1047
+ }
1048
+
1049
+ case Int8: {
1050
+ int8_t a;
1051
+ UNPACK_SINGLE(a, x->ptr, int8_t, t->flags);
1052
+ return equal_int64(a, y);
1053
+ }
1054
+
1055
+ case Int16: {
1056
+ int16_t a;
1057
+ UNPACK_SINGLE(a, x->ptr, int16_t, t->flags);
1058
+ return equal_int64(a, y);
1059
+ }
1060
+
1061
+ case Int32: {
1062
+ int32_t a;
1063
+ UNPACK_SINGLE(a, x->ptr, int32_t, t->flags);
1064
+ return equal_int64(a, y);
1065
+ }
1066
+
1067
+ case Int64: {
1068
+ int64_t a;
1069
+ UNPACK_SINGLE(a, x->ptr, int64_t, t->flags);
1070
+ return equal_int64(a, y);
1071
+ }
1072
+
1073
+ case Uint8: {
1074
+ uint8_t a;
1075
+ UNPACK_SINGLE(a, x->ptr, uint8_t, t->flags);
1076
+ return equal_uint64(a, y);
1077
+ }
1078
+
1079
+ case Uint16: {
1080
+ uint16_t a;
1081
+ UNPACK_SINGLE(a, x->ptr, uint16_t, t->flags);
1082
+ return equal_uint64(a, y);
1083
+ }
1084
+
1085
+ case Uint32: {
1086
+ uint32_t a;
1087
+ UNPACK_SINGLE(a, x->ptr, uint32_t, t->flags);
1088
+ return equal_uint64(a, y);
1089
+ }
1090
+
1091
+ case Uint64: {
1092
+ uint64_t a;
1093
+ UNPACK_SINGLE(a, x->ptr, uint64_t, t->flags);
1094
+ return equal_uint64(a, y);
1095
+ }
1096
+
1097
+ case Float16: {
1098
+ double a = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
1099
+ return equal_float64(a, y);
1100
+ }
1101
+
1102
+ case Float32: {
1103
+ double a = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
1104
+ return equal_float64(a, y);
1105
+ }
1106
+
1107
+ case Float64: {
1108
+ double a = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
1109
+ return equal_float64(a, y);
1110
+ }
1111
+
1112
+ case Complex32: {
1113
+ double real, imag;
1114
+
1115
+ real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
1116
+ imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
1117
+
1118
+ if (imag == 0.0) {
1119
+ return equal_float64(real, y);
1120
+ }
1121
+
1122
+ return equal_complex128(real, imag, y);
1123
+ }
1124
+
1125
+ case Complex64: {
1126
+ double real, imag;
1127
+
1128
+ real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
1129
+ imag = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
1130
+
1131
+ if (imag == 0.0) {
1132
+ return equal_float64(real, y);
1133
+ }
1134
+
1135
+ return equal_complex128(real, imag, y);
1136
+ }
1137
+
1138
+ case Complex128: {
1139
+ double real, imag;
1140
+
1141
+ real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
1142
+ imag = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
1143
+
1144
+ if (imag == 0.0) {
1145
+ return equal_float64(real, y);
1146
+ }
1147
+
1148
+ return equal_complex128(real, imag, y);
1149
+ }
1150
+
1151
+ case FixedString: {
1152
+ if (u->tag != FixedString ||
1153
+ u->FixedString.size != t->FixedString.size ||
1154
+ u->FixedString.encoding != t->FixedString.encoding ||
1155
+ u->datasize != t->datasize) {
1156
+ return 0;
1157
+ }
1158
+ return memcmp(x->ptr, y->ptr, (size_t)t->datasize) == 0;
1159
+ }
1160
+
1161
+ case FixedBytes: {
1162
+ if (u->tag != FixedBytes ||
1163
+ u->FixedBytes.size != t->FixedBytes.size ||
1164
+ u->datasize != t->datasize) {
1165
+ return 0;
1166
+ }
1167
+ return memcmp(x->ptr, y->ptr, (size_t)t->datasize) == 0;
1168
+ }
1169
+
1170
+ case String: {
1171
+ if (u->tag != String) {
1172
+ return 0;
1173
+ }
1174
+
1175
+ const char *a = XND_POINTER_DATA(x->ptr);
1176
+ const char *b = XND_POINTER_DATA(y->ptr);
1177
+ return strcmp(a, b) == 0;
1178
+ }
1179
+
1180
+ case Bytes: {
1181
+ char *a, *b;
1182
+ int64_t asize, bsize;
1183
+
1184
+ if (u->tag != Bytes) {
1185
+ return 0;
1186
+ }
1187
+
1188
+ asize = XND_BYTES_SIZE(x->ptr);
1189
+ bsize = XND_BYTES_SIZE(y->ptr);
1190
+
1191
+ a = (char *)XND_BYTES_DATA(x->ptr);
1192
+ b = (char *)XND_BYTES_DATA(y->ptr);
1193
+
1194
+ if (asize != bsize) {
1195
+ return 0;
1196
+ }
1197
+
1198
+ return memcmp(a, b, (size_t)asize) == 0;
1199
+ }
1200
+
1201
+ /* NOT REACHED: intercepted by equal_ref(). */
1202
+ case Ref:
1203
+
1204
+ /* NOT REACHED: xnd types must be concrete. */
1205
+ case Module: case Function:
1206
+ case AnyKind: case SymbolicDim: case EllipsisDim: case Typevar:
1207
+ case ScalarKind: case SignedKind: case UnsignedKind: case FloatKind:
1208
+ case ComplexKind: case FixedStringKind: case FixedBytesKind:
1209
+ ndt_err_format(ctx, NDT_RuntimeError, "unexpected abstract type");
1210
+ return -1;
1211
+ }
1212
+
1213
+ /* NOT REACHED: tags should be exhaustive */
1214
+ ndt_err_format(ctx, NDT_RuntimeError, "invalid type tag");
1215
+ return -1;
1216
+ }