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,313 @@
1
+ #ifndef CONTRIB_H
2
+ #define CONTRIB_H
3
+
4
+
5
+ #include <stdlib.h>
6
+ #include <stdint.h>
7
+ #include <inttypes.h>
8
+ #include <math.h>
9
+
10
+
11
+ /* PSF copyright: Written by Jim Hugunin and Chris Chase. */
12
+ static inline int64_t
13
+ xnd_slice_adjust_indices(int64_t length,
14
+ int64_t *start, int64_t *stop, int64_t step)
15
+ {
16
+ /* this is harder to get right than you might think */
17
+
18
+ assert(step != 0);
19
+ assert(step >= -INT64_MAX);
20
+
21
+ if (*start < 0) {
22
+ *start += length;
23
+ if (*start < 0) {
24
+ *start = (step < 0) ? -1 : 0;
25
+ }
26
+ }
27
+ else if (*start >= length) {
28
+ *start = (step < 0) ? length - 1 : length;
29
+ }
30
+
31
+ if (*stop < 0) {
32
+ *stop += length;
33
+ if (*stop < 0) {
34
+ *stop = (step < 0) ? -1 : 0;
35
+ }
36
+ }
37
+ else if (*stop >= length) {
38
+ *stop = (step < 0) ? length - 1 : length;
39
+ }
40
+
41
+ if (step < 0) {
42
+ if (*stop < *start) {
43
+ return (*start - *stop - 1) / (-step) + 1;
44
+ }
45
+ }
46
+ else {
47
+ if (*start < *stop) {
48
+ return (*stop - *start - 1) / step + 1;
49
+ }
50
+ }
51
+
52
+ return 0;
53
+ }
54
+
55
+ /* PSF copyright: Original by Eli Stevens and Mark Dickinson. */
56
+ static inline int
57
+ xnd_float_pack2(double x, unsigned char *p, int le, ndt_context_t *ctx)
58
+ {
59
+ unsigned char sign;
60
+ int e;
61
+ double f;
62
+ unsigned short bits;
63
+ int incr = 1;
64
+
65
+ if (x == 0.0) {
66
+ sign = (copysign(1.0, x) == -1.0);
67
+ e = 0;
68
+ bits = 0;
69
+ }
70
+ else if (isinf(x)) {
71
+ sign = (x < 0.0);
72
+ e = 0x1f;
73
+ bits = 0;
74
+ }
75
+ else if (isnan(x)) {
76
+ /* There are 2046 distinct half-precision NaNs (1022 signaling and
77
+ 1024 quiet), but there are only two quiet NaNs that don't arise by
78
+ quieting a signaling NaN; we get those by setting the topmost bit
79
+ of the fraction field and clearing all other fraction bits. We
80
+ choose the one with the appropriate sign. */
81
+ sign = (copysign(1.0, x) == -1.0);
82
+ e = 0x1f;
83
+ bits = 512;
84
+ }
85
+ else {
86
+ sign = (x < 0.0);
87
+ if (sign) {
88
+ x = -x;
89
+ }
90
+
91
+ f = frexp(x, &e);
92
+ if (f < 0.5 || f >= 1.0) {
93
+ ndt_err_format(ctx, NDT_RuntimeError,
94
+ "frexp() result out of range");
95
+ return -1;
96
+ }
97
+
98
+ /* Normalize f to be in the range [1.0, 2.0) */
99
+ f *= 2.0;
100
+ e--;
101
+
102
+ if (e >= 16) {
103
+ goto overflow;
104
+ }
105
+ else if (e < -25) {
106
+ /* |x| < 2**-25. Underflow to zero. */
107
+ f = 0.0;
108
+ e = 0;
109
+ }
110
+ else if (e < -14) {
111
+ /* |x| < 2**-14. Gradual underflow */
112
+ f = ldexp(f, 14 + e);
113
+ e = 0;
114
+ }
115
+ else /* if (!(e == 0 && f == 0.0)) */ {
116
+ e += 15;
117
+ f -= 1.0; /* Get rid of leading 1 */
118
+ }
119
+
120
+ f *= 1024.0; /* 2**10 */
121
+ /* Round to even */
122
+ bits = (unsigned short)f; /* Note the truncation */
123
+ assert(bits < 1024);
124
+ assert(e < 31);
125
+ if ((f - bits > 0.5) || ((f - bits == 0.5) && (bits % 2 == 1))) {
126
+ ++bits;
127
+ if (bits == 1024) {
128
+ /* The carry propagated out of a string of 10 1 bits. */
129
+ bits = 0;
130
+ ++e;
131
+ if (e == 31)
132
+ goto overflow;
133
+ }
134
+ }
135
+ }
136
+
137
+ bits |= (e << 10) | (sign << 15);
138
+
139
+ /* Write out result. */
140
+ if (le) {
141
+ p += 1;
142
+ incr = -1;
143
+ }
144
+
145
+ /* First byte */
146
+ *p = (unsigned char)((bits >> 8) & 0xFF);
147
+ p += incr;
148
+
149
+ /* Second byte */
150
+ *p = (unsigned char)(bits & 0xFF);
151
+
152
+ return 0;
153
+
154
+ overflow:
155
+ ndt_err_format(ctx, NDT_ValueError,
156
+ "float too large to pack with float16 type");
157
+ return -1;
158
+ }
159
+
160
+ /* PSF copyright: Original by Tim Peters. */
161
+ static inline int
162
+ xnd_float_pack4(double x, unsigned char *p, int le, ndt_context_t *ctx)
163
+ {
164
+ float y = (float)x;
165
+ int i, incr = 1;
166
+
167
+ if (isinf(y) && !isinf(x)) {
168
+ goto overflow;
169
+ }
170
+
171
+ unsigned char s[sizeof(float)];
172
+ memcpy(s, &y, sizeof(float));
173
+
174
+ if ((xnd_float_is_little_endian() && !le) ||
175
+ (xnd_float_is_big_endian() && le)) {
176
+ p += 3;
177
+ incr = -1;
178
+ }
179
+
180
+ for (i = 0; i < 4; i++) {
181
+ *p = s[i];
182
+ p += incr;
183
+ }
184
+
185
+ return 0;
186
+
187
+ overflow:
188
+ ndt_err_format(ctx, NDT_ValueError,
189
+ "float too large to pack with float32 type");
190
+ return -1;
191
+ }
192
+
193
+ /* PSF copyright: Original by Tim Peters. */
194
+ static inline void
195
+ xnd_float_pack8(double x, unsigned char *p, int le)
196
+ {
197
+ const unsigned char *s = (unsigned char*)&x;
198
+ int i, incr = 1;
199
+
200
+ if ((xnd_double_is_little_endian() && !le) ||
201
+ (xnd_double_is_big_endian() && le)) {
202
+ p += 7;
203
+ incr = -1;
204
+ }
205
+
206
+ for (i = 0; i < 8; i++) {
207
+ *p = *s++;
208
+ p += incr;
209
+ }
210
+ }
211
+
212
+ /* PSF copyright: Original by Eli Stevens and Mark Dickinson. */
213
+ static inline double
214
+ xnd_float_unpack2(const unsigned char *p, int le)
215
+ {
216
+ unsigned char sign;
217
+ int e;
218
+ unsigned int f;
219
+ double x;
220
+ int incr = 1;
221
+
222
+ if (le) {
223
+ p += 1;
224
+ incr = -1;
225
+ }
226
+
227
+ /* First byte */
228
+ sign = (*p >> 7) & 1;
229
+ e = (*p & 0x7C) >> 2;
230
+ f = (*p & 0x03) << 8;
231
+ p += incr;
232
+
233
+ /* Second byte */
234
+ f |= *p;
235
+
236
+ if (e == 0x1f) {
237
+ if (f == 0) {
238
+ /* Infinity */
239
+ return sign ? -INFINITY : INFINITY;
240
+ }
241
+ else {
242
+ /* NaN */
243
+ return sign ? -NAN : NAN;
244
+ }
245
+ }
246
+
247
+ x = (double)f / 1024.0;
248
+
249
+ if (e == 0) {
250
+ e = -14;
251
+ }
252
+ else {
253
+ x += 1.0;
254
+ e -= 15;
255
+ }
256
+ x = ldexp(x, e);
257
+
258
+ if (sign)
259
+ x = -x;
260
+
261
+ return x;
262
+ }
263
+
264
+ /* PSF copyright: Original by Tim Peters. */
265
+ static inline double
266
+ xnd_float_unpack4(const unsigned char *p, int le)
267
+ {
268
+ float x;
269
+
270
+ if ((xnd_float_is_little_endian() && !le) ||
271
+ (xnd_float_is_big_endian() && le)) {
272
+ char buf[4];
273
+ char *d = &buf[3];
274
+ int i;
275
+
276
+ for (i = 0; i < 4; i++) {
277
+ *d-- = *p++;
278
+ }
279
+ memcpy(&x, buf, 4);
280
+ }
281
+ else {
282
+ memcpy(&x, p, 4);
283
+ }
284
+
285
+ return x;
286
+ }
287
+
288
+ /* PSF copyright: Original by Tim Peters. */
289
+ static inline double
290
+ xnd_float_unpack8(const unsigned char *p, int le)
291
+ {
292
+ double x;
293
+
294
+ if ((xnd_double_is_little_endian() && !le) ||
295
+ (xnd_double_is_big_endian() && le)) {
296
+ char buf[8];
297
+ char *d = &buf[7];
298
+ int i;
299
+
300
+ for (i = 0; i < 8; i++) {
301
+ *d-- = *p++;
302
+ }
303
+ memcpy(&x, buf, 8);
304
+ }
305
+ else {
306
+ memcpy(&x, p, 8);
307
+ }
308
+
309
+ return x;
310
+ }
311
+
312
+
313
+ #endif /* CONTRIB_H */
@@ -0,0 +1,944 @@
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
+ /* Copying with exact casts */
46
+ /*****************************************************************************/
47
+
48
+ static int
49
+ type_error(ndt_context_t *ctx)
50
+ {
51
+ ndt_err_format(ctx, NDT_TypeError,
52
+ "incompatible types of source and destination in copy function");
53
+ return -1;
54
+ }
55
+
56
+ static int
57
+ value_error(ndt_context_t *ctx)
58
+ {
59
+ ndt_err_format(ctx, NDT_ValueError,
60
+ "incompatible value for destination type in copy function");
61
+ return -1;
62
+ }
63
+
64
+ /* Skip all ref chains. */
65
+ static int
66
+ copy_ref(xnd_t *y, const xnd_t *x, const uint32_t flags, ndt_context_t *ctx)
67
+ {
68
+ const ndt_t *t = x->type;
69
+ const ndt_t *u = y->type;
70
+ xnd_t xnext, ynext;
71
+
72
+ while (t->tag == Ref) {
73
+ xnext = xnd_ref_next(x, ctx);
74
+ if (xnext.ptr == NULL) {
75
+ return -1;
76
+ }
77
+ x = &xnext;
78
+ t = x->type;
79
+ }
80
+
81
+ while (u->tag == Ref) {
82
+ ynext = xnd_ref_next(y, ctx);
83
+ if (ynext.ptr == NULL) {
84
+ return -1;
85
+ }
86
+ y = &ynext;
87
+ u = y->type;
88
+ }
89
+
90
+ return xnd_copy(y, x, flags, ctx);
91
+ }
92
+
93
+ static int
94
+ copy_int64(xnd_t * const x, const int64_t i64, ndt_context_t *ctx)
95
+ {
96
+ const ndt_t * const t = x->type;
97
+
98
+ switch (t->tag) {
99
+ case Int8: {
100
+ if (i64 < INT8_MIN || i64 > INT8_MAX) {
101
+ return value_error(ctx);
102
+ }
103
+ int8_t i8 = (int8_t)i64;
104
+ PACK_SINGLE(x->ptr, i8, int8_t, t->flags);
105
+ return 0;
106
+ }
107
+
108
+ case Int16: {
109
+ if (i64 < INT16_MIN || i64 > INT16_MAX) {
110
+ return value_error(ctx);
111
+ }
112
+ int16_t i16 = (int16_t)i64;
113
+ PACK_SINGLE(x->ptr, i16, int16_t, t->flags);
114
+ return 0;
115
+ }
116
+
117
+ case Int32: {
118
+ if (i64 < INT32_MIN || i64 > INT32_MAX) {
119
+ return value_error(ctx);
120
+ }
121
+ int32_t i32 = (int32_t)i64;
122
+ PACK_SINGLE(x->ptr, i32, int32_t, t->flags);
123
+ return 0;
124
+ }
125
+
126
+ case Int64: {
127
+ PACK_SINGLE(x->ptr, i64, int64_t, t->flags);
128
+ return 0;
129
+ }
130
+
131
+ case Uint8: {
132
+ if (i64 < 0 || i64 > UINT8_MAX) {
133
+ return value_error(ctx);
134
+ }
135
+ uint8_t u8 = (uint8_t)i64;
136
+ PACK_SINGLE(x->ptr, u8, uint8_t, t->flags);
137
+ return 0;
138
+ }
139
+
140
+ case Uint16: {
141
+ if (i64 < 0 || i64 > UINT16_MAX) {
142
+ return value_error(ctx);
143
+ }
144
+ uint16_t u16 = (uint16_t)i64;;
145
+ PACK_SINGLE(x->ptr, u16, uint16_t, t->flags);
146
+ return 0;
147
+ }
148
+
149
+ case Uint32: {
150
+ if (i64 < 0 || i64 > UINT32_MAX) {
151
+ return value_error(ctx);
152
+ }
153
+ uint32_t u32 = (uint32_t)i64;
154
+ PACK_SINGLE(x->ptr, u32, uint32_t, t->flags);
155
+ return 0;
156
+ }
157
+
158
+ case Uint64: {
159
+ if (i64 < 0) {
160
+ return value_error(ctx);
161
+ }
162
+ uint64_t u64 = (uint64_t)i64;
163
+ PACK_SINGLE(x->ptr, u64, uint64_t, t->flags);
164
+ return 0;
165
+ }
166
+
167
+ case Float16: {
168
+ if (i64 < -4503599627370496LL || i64 > 4503599627370496LL) {
169
+ return value_error(ctx);
170
+ }
171
+ double real = (double)i64;
172
+ return xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx);
173
+ }
174
+
175
+ case Float32: {
176
+ if (i64 < -4503599627370496LL || i64 > 4503599627370496LL) {
177
+ return value_error(ctx);
178
+ }
179
+ double real = (double)i64;
180
+ return xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx);
181
+ }
182
+
183
+ case Float64: {
184
+ if (i64 < -4503599627370496LL || i64 > 4503599627370496LL) {
185
+ return value_error(ctx);
186
+ }
187
+ double real = (double)i64;
188
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
189
+ return 0;
190
+ }
191
+
192
+ case Complex32: {
193
+ if (i64 < -4503599627370496LL || i64 > 4503599627370496LL) {
194
+ return value_error(ctx);
195
+ }
196
+
197
+ double real = (double)i64;
198
+ double imag = 0.0;
199
+
200
+ if (xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
201
+ return -1;
202
+ }
203
+
204
+ return xnd_float_pack2(imag, (unsigned char *)(x->ptr+2), le(t->flags), ctx);
205
+ }
206
+
207
+ case Complex64: {
208
+ if (i64 < -4503599627370496LL || i64 > 4503599627370496LL) {
209
+ return value_error(ctx);
210
+ }
211
+
212
+ double real = (double)i64;
213
+ double imag = 0.0;
214
+
215
+ if (xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
216
+ return -1;
217
+ }
218
+
219
+ return xnd_float_pack4(imag, (unsigned char *)(x->ptr+4), le(t->flags), ctx);
220
+ }
221
+
222
+ case Complex128: {
223
+ if (i64 < -4503599627370496LL || i64 > 4503599627370496LL) {
224
+ return value_error(ctx);
225
+ }
226
+
227
+ double real = (double)i64;
228
+ double imag = 0.0;
229
+
230
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
231
+ xnd_float_pack8(imag, (unsigned char *)(x->ptr+8), le(t->flags));
232
+
233
+ return 0;
234
+ }
235
+
236
+ default:
237
+ return type_error(ctx);
238
+ }
239
+ }
240
+
241
+ static int
242
+ copy_uint64(xnd_t * const x, const uint64_t u64, ndt_context_t *ctx)
243
+ {
244
+ const ndt_t * const t = x->type;
245
+
246
+ switch (t->tag) {
247
+ case Int8: {
248
+ if (u64 > INT8_MAX) {
249
+ return value_error(ctx);
250
+ }
251
+ int8_t i8 = (int8_t)u64;
252
+ PACK_SINGLE(x->ptr, i8, int8_t, t->flags);
253
+ return 0;
254
+ }
255
+
256
+ case Int16: {
257
+ if (u64 > INT16_MAX) {
258
+ return value_error(ctx);
259
+ }
260
+ int16_t i16 = (int16_t)u64;
261
+ PACK_SINGLE(x->ptr, i16, int16_t, t->flags);
262
+ return 0;
263
+ }
264
+
265
+ case Int32: {
266
+ if (u64 > INT32_MAX) {
267
+ return value_error(ctx);
268
+ }
269
+ int32_t i32 = (int32_t)u64;
270
+ PACK_SINGLE(x->ptr, i32, int32_t, t->flags);
271
+ return 0;
272
+ }
273
+
274
+ case Int64: {
275
+ if (u64 > INT64_MAX) {
276
+ return value_error(ctx);
277
+ }
278
+ int64_t i64 = (int64_t)u64;
279
+ PACK_SINGLE(x->ptr, i64, int64_t, t->flags);
280
+ return 0;
281
+ }
282
+
283
+ case Uint8: {
284
+ if (u64 > UINT8_MAX) {
285
+ return value_error(ctx);
286
+ }
287
+ uint8_t u8 = (uint8_t)u64;
288
+ PACK_SINGLE(x->ptr, u8, uint8_t, t->flags);
289
+ return 0;
290
+ }
291
+
292
+ case Uint16: {
293
+ if (u64 > UINT16_MAX) {
294
+ return value_error(ctx);
295
+ }
296
+ uint16_t u16 = (uint16_t)u64;
297
+ PACK_SINGLE(x->ptr, u16, uint16_t, t->flags);
298
+ return 0;
299
+ }
300
+
301
+ case Uint32: {
302
+ if (u64 > UINT32_MAX) {
303
+ return value_error(ctx);
304
+ }
305
+ uint32_t u32 = (uint32_t)u64;
306
+ PACK_SINGLE(x->ptr, u32, uint32_t, t->flags);
307
+ return 0;
308
+ }
309
+
310
+ case Uint64: {
311
+ PACK_SINGLE(x->ptr, u64, uint64_t, t->flags);
312
+ return 0;
313
+ }
314
+
315
+ case Float16: {
316
+ if (u64 > 4503599627370496LL) {
317
+ return value_error(ctx);
318
+ }
319
+ double real = (double)u64;
320
+ return xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx);
321
+ }
322
+
323
+ case Float32: {
324
+ if (u64 > 4503599627370496LL) {
325
+ return value_error(ctx);
326
+ }
327
+ double real = (double)u64;
328
+ return xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx);
329
+ }
330
+
331
+ case Float64: {
332
+ if (u64 > 4503599627370496LL) {
333
+ return value_error(ctx);
334
+ }
335
+ double real = (double)u64;
336
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
337
+ return 0;
338
+ }
339
+
340
+ case Complex32: {
341
+ if (u64 > 4503599627370496LL) {
342
+ return value_error(ctx);
343
+ }
344
+
345
+ double real = (double)u64;
346
+ double imag = 0.0;
347
+
348
+ if (xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
349
+ return -1;
350
+ }
351
+
352
+ return xnd_float_pack2(imag, (unsigned char *)x->ptr+2, le(t->flags), ctx);
353
+ }
354
+
355
+ case Complex64: {
356
+ if (u64 > 4503599627370496LL) {
357
+ return value_error(ctx);
358
+ }
359
+
360
+ double real = (double)u64;
361
+ double imag = 0.0;
362
+
363
+ if (xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
364
+ return -1;
365
+ }
366
+
367
+ return xnd_float_pack4(imag, (unsigned char *)(x->ptr+4), le(t->flags), ctx);
368
+ }
369
+
370
+ case Complex128: {
371
+ if (u64 > 4503599627370496LL) {
372
+ return value_error(ctx);
373
+ }
374
+
375
+ double real = (double)u64;
376
+ double imag = 0.0;
377
+
378
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
379
+ xnd_float_pack8(imag, (unsigned char *)(x->ptr+8), le(t->flags));
380
+ return 0;
381
+ }
382
+
383
+ default:
384
+ return type_error(ctx);
385
+ }
386
+ }
387
+
388
+ static inline bool
389
+ isint(double real)
390
+ {
391
+ double intpart;
392
+ double fracpart;
393
+
394
+ fracpart = modf(real, &intpart);
395
+ if (fracpart == 0.0) {
396
+ return (!isinf(intpart) && !isnan(intpart));
397
+ }
398
+
399
+ return false;
400
+ }
401
+
402
+ static int
403
+ copy_float64(xnd_t * const x, const double real, ndt_context_t *ctx)
404
+ {
405
+ const ndt_t * const t = x->type;
406
+
407
+ switch (t->tag) {
408
+ case Int8: {
409
+ if (!isint(real) || real < INT8_MIN || real > INT8_MAX) {
410
+ return value_error(ctx);
411
+ }
412
+ int8_t i8 = (int8_t)real;
413
+ PACK_SINGLE(x->ptr, i8, int8_t, t->flags);
414
+ return 0;
415
+ }
416
+
417
+ case Int16: {
418
+ if (!isint(real) || real < INT16_MIN || real > INT16_MAX) {
419
+ return value_error(ctx);
420
+ }
421
+ int16_t i16 = (int16_t)real;
422
+ PACK_SINGLE(x->ptr, i16, int16_t, t->flags);
423
+ return 0;
424
+ }
425
+
426
+ case Int32: {
427
+ if (!isint(real) || real < INT32_MIN || real > INT32_MAX) {
428
+ return value_error(ctx);
429
+ }
430
+ int32_t i32 = (int32_t)real;
431
+ PACK_SINGLE(x->ptr, i32, int32_t, t->flags);
432
+ return 0;
433
+ }
434
+
435
+ case Int64: {
436
+ if (!isint(real) || real < -4503599627370496LL || real > 4503599627370496LL) {
437
+ return value_error(ctx);
438
+ }
439
+ int64_t i64 = (int64_t)real;
440
+ PACK_SINGLE(x->ptr, i64, int64_t, t->flags);
441
+ return 0;
442
+ }
443
+
444
+ case Uint8: {
445
+ if (!isint(real) || real < 0 || real > UINT8_MAX) {
446
+ return value_error(ctx);
447
+ }
448
+ uint8_t u8 = (uint8_t)real;
449
+ PACK_SINGLE(x->ptr, u8, uint8_t, t->flags);
450
+ return 0;
451
+ }
452
+
453
+ case Uint16: {
454
+ if (!isint(real) || real < 0 || real > UINT16_MAX) {
455
+ return value_error(ctx);
456
+ }
457
+ uint16_t u16 = (uint16_t)real;
458
+ PACK_SINGLE(x->ptr, u16, uint16_t, t->flags);
459
+ return 0;
460
+ }
461
+
462
+ case Uint32: {
463
+ if (!isint(real) || real < 0 || real > UINT32_MAX) {
464
+ return value_error(ctx);
465
+ }
466
+ uint32_t u32 = (uint32_t)real;
467
+ PACK_SINGLE(x->ptr, u32, uint32_t, t->flags);
468
+ return 0;
469
+ }
470
+
471
+ case Uint64: {
472
+ if (!isint(real) || real < 0 || real > 4503599627370496ULL) {
473
+ return value_error(ctx);
474
+ }
475
+ uint64_t u64 = (uint64_t)real;
476
+ PACK_SINGLE(x->ptr, u64, uint64_t, t->flags);
477
+ }
478
+
479
+ case Float16: {
480
+ return xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx);
481
+ }
482
+
483
+ case Float32: {
484
+ return xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx);
485
+ }
486
+
487
+ case Float64: {
488
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
489
+ return 0;
490
+ }
491
+
492
+ case Complex32: {
493
+ double imag = 0.0;
494
+
495
+ if (xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
496
+ return -1;
497
+ }
498
+
499
+ return xnd_float_pack2(imag, (unsigned char *)(x->ptr+2), le(t->flags), ctx);
500
+ }
501
+
502
+ case Complex64: {
503
+ double imag = 0.0;
504
+
505
+ if (xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
506
+ return -1;
507
+ }
508
+
509
+ return xnd_float_pack4(imag, (unsigned char *)(x->ptr+4), le(t->flags), ctx);
510
+ }
511
+
512
+ case Complex128: {
513
+ double imag = 0.0;
514
+
515
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
516
+ xnd_float_pack8(imag, (unsigned char *)(x->ptr+8), le(t->flags));
517
+
518
+ return 0;
519
+ }
520
+
521
+ default:
522
+ return type_error(ctx);
523
+ }
524
+ }
525
+
526
+ static int
527
+ copy_complex128(xnd_t * const x, const double real, const double imag,
528
+ ndt_context_t *ctx)
529
+ {
530
+ const ndt_t * const t = x->type;
531
+
532
+ switch (t->tag) {
533
+ case Int8: case Int16: case Int32: case Int64:
534
+ case Uint8: case Uint16: case Uint32: case Uint64:
535
+ case Float16: case Float32: case Float64: {
536
+ if (imag == 0.0) {
537
+ return copy_float64(x, real, ctx);
538
+ }
539
+
540
+ return type_error(ctx);
541
+ }
542
+
543
+ case Complex32: {
544
+ if (xnd_float_pack2(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
545
+ return -1;
546
+ }
547
+ return xnd_float_pack2(imag, (unsigned char *)(x->ptr+2), le(t->flags), ctx);
548
+ }
549
+
550
+ case Complex64: {
551
+ if (xnd_float_pack4(real, (unsigned char *)x->ptr, le(t->flags), ctx) < 0) {
552
+ return -1;
553
+ }
554
+ return xnd_float_pack4(imag, (unsigned char *)(x->ptr+4), le(t->flags), ctx);
555
+ }
556
+
557
+ case Complex128: {
558
+ xnd_float_pack8(real, (unsigned char *)x->ptr, le(t->flags));
559
+ xnd_float_pack8(imag, (unsigned char *)(x->ptr+8), le(t->flags));
560
+ return 0;
561
+ }
562
+
563
+ default:
564
+ return type_error(ctx);
565
+ }
566
+ }
567
+
568
+ int
569
+ xnd_copy(xnd_t *y, const xnd_t *x, uint32_t flags, ndt_context_t *ctx)
570
+ {
571
+ const ndt_t * const t = x->type;
572
+ const ndt_t * const u = y->type;
573
+ int n;
574
+
575
+ if (xnd_is_na(x)) {
576
+ if (!ndt_is_optional(u)) {
577
+ ndt_err_format(ctx, NDT_TypeError,
578
+ "cannot copy NA to destination with non-optional type");
579
+ return -1;
580
+ }
581
+
582
+ xnd_set_na(y);
583
+ return 0;
584
+ }
585
+
586
+ if (t->tag == Ref || u->tag == Ref) {
587
+ return copy_ref(y, x, flags, ctx);
588
+ }
589
+
590
+ switch (t->tag) {
591
+ case FixedDim: {
592
+ int64_t i;
593
+
594
+ if (u->tag != FixedDim || u->FixedDim.shape != t->FixedDim.shape) {
595
+ return type_error(ctx);
596
+ }
597
+
598
+ for (i = 0; i < t->FixedDim.shape; i++) {
599
+ const xnd_t xnext = xnd_fixed_dim_next(x, i);
600
+ xnd_t ynext = xnd_fixed_dim_next(y, i);
601
+ n = xnd_copy(&ynext, &xnext, flags, ctx);
602
+ if (n < 0) return n;
603
+ }
604
+
605
+ return 0;
606
+ }
607
+
608
+ case VarDim: {
609
+ int64_t xstart, xstep, xshape;
610
+ int64_t ystart, ystep, yshape;
611
+ int64_t i;
612
+
613
+ if (u->tag != VarDim) {
614
+ return type_error(ctx);
615
+ }
616
+
617
+ xshape = ndt_var_indices(&xstart, &xstep, t, x->index, ctx);
618
+ if (xshape < 0) {
619
+ return -1;
620
+ }
621
+
622
+ yshape = ndt_var_indices(&ystart, &ystep, u, y->index, ctx);
623
+ if (yshape < 0) {
624
+ return -1;
625
+ }
626
+
627
+ if (yshape != xshape) {
628
+ return type_error(ctx);
629
+ }
630
+
631
+ for (i = 0; i < xshape; i++) {
632
+ const xnd_t xnext = xnd_var_dim_next(x, xstart, xstep, i);
633
+ xnd_t ynext = xnd_var_dim_next(y, ystart, ystep, i);
634
+ n = xnd_copy(&ynext, &xnext, flags, ctx);
635
+ if (n < 0) return n;
636
+ }
637
+
638
+ return 0;
639
+ }
640
+
641
+ case Tuple: {
642
+ if (u->tag != Tuple || u->Tuple.shape != t->Tuple.shape) {
643
+ return type_error(ctx);
644
+ }
645
+
646
+ for (int64_t i = 0; i < t->Tuple.shape; i++) {
647
+ const xnd_t xnext = xnd_tuple_next(x, i, ctx);
648
+ if (xnext.ptr == NULL) {
649
+ return -1;
650
+ }
651
+
652
+ xnd_t ynext = xnd_tuple_next(y, i, ctx);
653
+ if (ynext.ptr == NULL) {
654
+ return -1;
655
+ }
656
+
657
+ n = xnd_copy(&ynext, &xnext, flags, ctx);
658
+ if (n < 0) return n;
659
+ }
660
+
661
+ return 0;
662
+ }
663
+
664
+ case Record: {
665
+ if (u->tag != Record || u->Record.shape != t->Record.shape) {
666
+ return type_error(ctx);
667
+ }
668
+
669
+ for (int64_t i = 0; i < t->Record.shape; i++) {
670
+ if (strcmp(t->Record.names[i], u->Record.names[i]) != 0) {
671
+ return type_error(ctx);
672
+ }
673
+
674
+ const xnd_t xnext = xnd_record_next(x, i, ctx);
675
+ if (xnext.ptr == NULL) {
676
+ return -1;
677
+ }
678
+
679
+ xnd_t ynext = xnd_record_next(y, i, ctx);
680
+ if (ynext.ptr == NULL) {
681
+ return -1;
682
+ }
683
+
684
+ n = xnd_copy(&ynext, &xnext, flags, ctx);
685
+ if (n < 0) return n;
686
+ }
687
+
688
+ return 0;
689
+ }
690
+
691
+ case Constr: {
692
+ if (u->tag != Constr || strcmp(u->Constr.name, t->Constr.name) != 0) {
693
+ return type_error(ctx);
694
+ }
695
+
696
+ const xnd_t xnext = xnd_constr_next(x, ctx);
697
+ if (xnext.ptr == NULL) {
698
+ return -1;
699
+ }
700
+
701
+ xnd_t ynext = xnd_constr_next(y, ctx);
702
+ if (ynext.ptr == NULL) {
703
+ return -1;
704
+ }
705
+
706
+ return xnd_copy(&ynext, &xnext, flags, ctx);
707
+ }
708
+
709
+ case Nominal: {
710
+ if (u->tag != Nominal) {
711
+ return type_error(ctx);
712
+ }
713
+
714
+ if (strcmp(t->Nominal.name, u->Nominal.name) != 0) {
715
+ return type_error(ctx);
716
+ }
717
+
718
+ const xnd_t xnext = xnd_nominal_next(x, ctx);
719
+ if (xnext.ptr == NULL) {
720
+ return -1;
721
+ }
722
+
723
+ xnd_t ynext = xnd_nominal_next(y, ctx);
724
+ if (ynext.ptr == NULL) {
725
+ return -1;
726
+ }
727
+
728
+ return xnd_copy(&ynext, &xnext, flags, ctx);
729
+ }
730
+
731
+ case Categorical: {
732
+ int64_t i64;
733
+
734
+ if (!ndt_equal(t, u)) {
735
+ return type_error(ctx);
736
+ }
737
+
738
+ UNPACK_SINGLE(i64, x->ptr, int64_t, t->flags);
739
+ PACK_SINGLE(y->ptr, i64, int64_t, u->flags);
740
+ return 0;
741
+ }
742
+
743
+ case Char: {
744
+ ndt_err_format(ctx, NDT_NotImplementedError, "char not implemented");
745
+ return -1;
746
+ }
747
+
748
+ case Bool: {
749
+ bool b;
750
+
751
+ if (u->tag != Bool) {
752
+ return type_error(ctx);
753
+ }
754
+
755
+ UNPACK_SINGLE(b, x->ptr, bool, u->flags);
756
+ PACK_SINGLE(y->ptr, b, bool, t->flags);
757
+ return 0;
758
+ }
759
+
760
+ case Int8: {
761
+ int8_t i8;
762
+ UNPACK_SINGLE(i8, x->ptr, int8_t, t->flags);
763
+ return copy_int64(y, i8, ctx);
764
+ }
765
+
766
+ case Int16: {
767
+ int16_t i16;
768
+ UNPACK_SINGLE(i16, x->ptr, int16_t, t->flags);
769
+ return copy_int64(y, i16, ctx);
770
+ }
771
+
772
+ case Int32: {
773
+ int32_t i32;
774
+ UNPACK_SINGLE(i32, x->ptr, int32_t, t->flags);
775
+ return copy_int64(y, i32, ctx);
776
+ }
777
+
778
+ case Int64: {
779
+ int64_t i64;
780
+ UNPACK_SINGLE(i64, x->ptr, int64_t, t->flags);
781
+ return copy_int64(y, i64, ctx);
782
+ }
783
+
784
+ case Uint8: {
785
+ uint8_t u8;
786
+ UNPACK_SINGLE(u8, x->ptr, uint8_t, t->flags);
787
+ return copy_uint64(y, u8, ctx);
788
+ }
789
+
790
+ case Uint16: {
791
+ uint16_t u16;
792
+ UNPACK_SINGLE(u16, x->ptr, uint16_t, t->flags);
793
+ return copy_uint64(y, u16, ctx);
794
+ }
795
+
796
+ case Uint32: {
797
+ uint32_t u32;
798
+ UNPACK_SINGLE(u32, x->ptr, uint32_t, t->flags);
799
+ return copy_uint64(y, u32, ctx);
800
+ }
801
+
802
+ case Uint64: {
803
+ uint64_t u64;
804
+ UNPACK_SINGLE(u64, x->ptr, uint64_t, t->flags);
805
+ return copy_uint64(y, u64, ctx);
806
+ }
807
+
808
+ case Float16: {
809
+ double real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
810
+ return copy_float64(y, real, ctx);
811
+ }
812
+
813
+ case Float32: {
814
+ double real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
815
+ return copy_float64(y, real, ctx);
816
+ }
817
+
818
+ case Float64: {
819
+ double real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
820
+ return copy_float64(y, real, ctx);
821
+ }
822
+
823
+ case Complex32: {
824
+ double real, imag;
825
+
826
+ real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
827
+ imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
828
+
829
+ return copy_complex128(y, real, imag, ctx);
830
+ }
831
+
832
+ case Complex64: {
833
+ double real, imag;
834
+
835
+ real = xnd_float_unpack4((unsigned char *)x->ptr, le(t->flags));
836
+ imag = xnd_float_unpack4((unsigned char *)(x->ptr+4), le(t->flags));
837
+
838
+ return copy_complex128(y, real, imag, ctx);
839
+ }
840
+
841
+ case Complex128: {
842
+ double real, imag;
843
+
844
+ real = xnd_float_unpack8((unsigned char *)x->ptr, le(t->flags));
845
+ imag = xnd_float_unpack8((unsigned char *)(x->ptr+8), le(t->flags));
846
+
847
+ return copy_complex128(y, real, imag, ctx);
848
+ }
849
+
850
+ case FixedString: {
851
+ if (u->tag != FixedString ||
852
+ u->FixedString.size != t->FixedString.size ||
853
+ u->FixedString.encoding != t->FixedString.encoding ||
854
+ u->datasize != t->datasize) {
855
+ return type_error(ctx);
856
+ }
857
+ memcpy(y->ptr, x->ptr, (size_t)t->datasize);
858
+ return 0;
859
+ }
860
+
861
+ case FixedBytes: {
862
+ if (u->tag != FixedBytes ||
863
+ u->FixedBytes.size != t->FixedBytes.size ||
864
+ u->datasize != t->datasize) {
865
+ return type_error(ctx);
866
+ }
867
+ memcpy(y->ptr, x->ptr, (size_t)t->datasize);
868
+ return 0;
869
+ }
870
+
871
+ case String: {
872
+ char *s;
873
+
874
+ if (u->tag != String) {
875
+ return type_error(ctx);
876
+ }
877
+
878
+ s = ndt_strdup(XND_POINTER_DATA(x->ptr), ctx);
879
+ if (s == NULL) {
880
+ return -1;
881
+ }
882
+
883
+ if (XND_POINTER_DATA(y->ptr) != NULL) {
884
+ if (!(flags & XND_OWN_EMBEDDED)) {
885
+ ndt_err_format(ctx, NDT_RuntimeError,
886
+ "cannot free string pointer, xnd does not own it");
887
+ ndt_free(s);
888
+ return -1;
889
+ }
890
+ ndt_free(XND_POINTER_DATA(y->ptr));
891
+ }
892
+
893
+ XND_POINTER_DATA(y->ptr) = s;
894
+ return 0;
895
+ }
896
+
897
+ case Bytes: {
898
+ unsigned char *s;
899
+ int64_t size;
900
+
901
+ if (u->tag != Bytes) {
902
+ return type_error(ctx);
903
+ }
904
+
905
+ size = XND_BYTES_SIZE(x->ptr);
906
+
907
+ s = ndt_aligned_calloc(u->Bytes.target_align, size);
908
+ if (s == NULL) {
909
+ (void)ndt_memory_error(ctx);
910
+ return -1;
911
+ }
912
+ memcpy(s, XND_BYTES_DATA(x->ptr), (size_t)size);
913
+
914
+ if (XND_BYTES_DATA(y->ptr) != NULL) {
915
+ if (!(flags & XND_OWN_EMBEDDED)) {
916
+ ndt_err_format(ctx, NDT_RuntimeError,
917
+ "cannot free string pointer, xnd does not own it");
918
+ ndt_aligned_free(s);
919
+ return -1;
920
+ }
921
+ ndt_aligned_free(XND_BYTES_DATA(y->ptr));
922
+ }
923
+
924
+ XND_BYTES_SIZE(y->ptr) = size;
925
+ XND_BYTES_DATA(y->ptr) = s;
926
+ return 0;
927
+ }
928
+
929
+ /* NOT REACHED: intercepted by equal_ref(). */
930
+ case Ref:
931
+
932
+ /* NOT REACHED: xnd types must be concrete. */
933
+ case Module: case Function:
934
+ case AnyKind: case SymbolicDim: case EllipsisDim: case Typevar:
935
+ case ScalarKind: case SignedKind: case UnsignedKind: case FloatKind:
936
+ case ComplexKind: case FixedStringKind: case FixedBytesKind:
937
+ ndt_err_format(ctx, NDT_RuntimeError, "unexpected abstract type");
938
+ return -1;
939
+ }
940
+
941
+ /* NOT REACHED: tags should be exhaustive */
942
+ ndt_err_format(ctx, NDT_RuntimeError, "invalid type tag");
943
+ return -1;
944
+ }