carray 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/CHANGELOG.md +845 -3
- data/{NEWS.md → CHANGELOG.v1.md} +1 -1
- data/README.md +33 -33
- data/carray.gemspec +12 -8
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +256 -114
- data/ext/ca_binop_dispatch.c +5 -6
- data/ext/ca_binop_dispatch.h +0 -7
- data/ext/ca_categorical_iterator.c +121 -67
- data/ext/ca_for_each_element.h +6 -8
- data/ext/ca_group_iter.c +1 -1
- data/ext/ca_kernel_iterator.c +386 -74
- data/ext/ca_kernel_iterator.h +145 -45
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_bincmp.c +57 -27
- data/ext/ca_obj_binop.c +86 -30
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +88 -27
- data/ext/ca_obj_face.c +104 -0
- data/ext/ca_obj_face.h +48 -1
- data/ext/ca_obj_fake.c +11 -0
- data/ext/ca_obj_fixlen_string.c +21 -6
- data/ext/ca_obj_grid.c +11 -3
- data/ext/ca_obj_meld.c +125 -22
- data/ext/ca_obj_moncmp.c +33 -14
- data/ext/ca_obj_monop.c +19 -7
- data/ext/ca_obj_object.c +107 -4
- data/ext/ca_obj_record.c +3 -1
- data/ext/ca_obj_refer.c +30 -6
- data/ext/ca_obj_roll.c +13 -5
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_select_axis.c +16 -6
- data/ext/ca_obj_shift.c +3 -3
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +178 -24
- data/ext/ca_obj_string.c +11 -5
- data/ext/ca_obj_tile.c +13 -5
- data/ext/ca_obj_time.c +3 -1
- data/ext/ca_obj_timedelta.c +3 -1
- data/ext/ca_obj_transpose.c +1 -1
- data/ext/ca_obj_triop.c +62 -23
- data/ext/ca_obj_window.c +94 -19
- data/ext/ca_op_cmplx64.h +123 -0
- data/ext/ca_op_ipower.c +1 -5
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +5 -5
- data/ext/ca_sweep_engine.c +362 -155
- data/ext/ca_sweep_engine.h +39 -9
- data/ext/ca_transform_common.c +7 -0
- data/ext/carray.h +148 -132
- data/ext/carray_access.c +83 -49
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_bincount.c +8 -8
- data/ext/carray_broadcast.c +102 -9
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +2010 -335
- data/ext/carray_call_cfunc.h +153 -0
- data/ext/carray_cast.c +184 -72
- data/ext/carray_conversion.c +22 -22
- data/ext/carray_copy.c +67 -32
- data/ext/carray_core.c +140 -13
- data/ext/carray_count.c +10 -11
- data/ext/carray_element.c +7 -7
- data/ext/carray_factorize.c +72 -51
- data/ext/carray_hold.c +1 -1
- data/ext/carray_index_classifier.c +7 -21
- data/ext/carray_internal.h +36 -3
- data/ext/carray_kernels_bincmp.c +1 -0
- data/ext/carray_kernels_binop.c +320 -298
- data/ext/carray_kernels_init.c +1095 -0
- data/ext/carray_kernels_map.c +1 -0
- data/ext/carray_kernels_moncmp.c +1 -0
- data/ext/carray_kernels_monop.c +412 -411
- data/ext/carray_kernels_reduce_aggregate.c +256 -87
- data/ext/carray_kernels_reduce_boolean.c +1 -0
- data/ext/carray_kernels_reduce_cumulative.c +324 -54
- data/ext/carray_kernels_reduce_extreme.c +605 -58
- data/ext/carray_kernels_reduce_variance.c +1 -0
- data/ext/carray_kernels_scan.c +5 -4
- data/ext/carray_kernels_search.c +187 -106
- data/ext/carray_kernels_sort.c +1 -0
- data/ext/carray_kernels_triop.c +1 -0
- data/ext/carray_lazy.c +175 -5
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +29 -13
- data/ext/carray_median_percentile.c +56 -1
- data/ext/carray_memory_view.c +46 -21
- data/ext/carray_operator.c +50 -53
- data/ext/carray_order.c +1 -1
- data/ext/carray_partition.c +4 -4
- data/ext/carray_random.c +391 -47
- data/ext/carray_scatter.c +1 -1
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +22 -24
- data/ext/carray_sort_kernel.c +10 -10
- data/ext/carray_test.c +1 -1
- data/ext/extconf.rb +18 -0
- data/ext/mk_call_cfunc.rb +323 -145
- data/ext/mkkernel.rb +651 -129
- data/ext/ruby_carray.c +28 -17
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +14 -1
- data/lib/carray/axis_group.rb +84 -7
- data/lib/carray/basics.rb +63 -59
- data/lib/carray/bincount_nd.rb +12 -12
- data/lib/carray/block_iterator.rb +111 -25
- data/lib/carray/categorical.rb +154 -37
- data/lib/carray/categorical_iterator.rb +300 -151
- data/lib/carray/conditional.rb +14 -14
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +61 -0
- data/lib/carray/core_extensions.rb +62 -5
- data/lib/carray/data_type_extension.rb +21 -1
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +3 -3
- data/lib/carray/frame/convert.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +85 -21
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +224 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/sort.rb +1 -1
- data/lib/carray/frame/verbs.rb +32 -12
- data/lib/carray/fuse_source.rb +123 -0
- data/lib/carray/fusion.rb +218 -0
- data/lib/carray/histogram.rb +16 -16
- data/lib/carray/inspect.rb +43 -16
- data/lib/carray/iterator.rb +147 -3
- data/lib/carray/lazy.rb +88 -73
- data/lib/carray/mask_gap_fill.rb +3 -1
- data/lib/carray/meld_reduce.rb +2 -2
- data/lib/carray/methods/align_addr.rb +1 -1
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/is_in.rb +25 -14
- data/lib/carray/methods/locate_addr.rb +81 -3
- data/lib/carray/methods/mask_duplicates.rb +36 -2
- data/lib/carray/methods/meshgrid.rb +4 -5
- data/lib/carray/methods/mode.rb +2 -2
- data/lib/carray/methods/nunique.rb +23 -2
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/snap.rb +7 -2
- data/lib/carray/methods/unique.rb +44 -4
- data/lib/carray/methods/value_counts.rb +2 -2
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +0 -19
- data/lib/carray/slab_iterator.rb +77 -19
- data/lib/carray/string_operation_extension.rb +10 -6
- data/lib/carray/time.rb +906 -491
- data/lib/carray/window_iterator.rb +421 -27
- data/lib/carray.rb +7 -5
- data/yard-stubs/ca_obj_array.rb +385 -0
- data/yard-stubs/ca_obj_bitarray.rb +38 -0
- data/yard-stubs/ca_obj_bitfield.rb +43 -0
- data/yard-stubs/ca_obj_block.rb +68 -0
- data/yard-stubs/ca_obj_byte_swap.rb +56 -0
- data/yard-stubs/ca_obj_fake.rb +31 -0
- data/yard-stubs/ca_obj_farray.rb +32 -0
- data/yard-stubs/ca_obj_field.rb +45 -0
- data/yard-stubs/ca_obj_grid.rb +35 -0
- data/yard-stubs/ca_obj_refer.rb +72 -0
- data/yard-stubs/ca_obj_roll.rb +45 -0
- data/yard-stubs/ca_obj_shift.rb +43 -0
- data/yard-stubs/ca_obj_stride.rb +181 -0
- data/yard-stubs/ca_obj_tile.rb +29 -0
- data/yard-stubs/ca_obj_transpose.rb +40 -0
- data/yard-stubs/ca_obj_window.rb +57 -0
- data/yard-stubs/carray_access.rb +131 -0
- data/yard-stubs/carray_attribute.rb +246 -0
- data/yard-stubs/carray_broadcast.rb +37 -0
- data/yard-stubs/carray_cast.rb +489 -0
- data/yard-stubs/carray_class.rb +65 -0
- data/yard-stubs/carray_conversion.rb +76 -0
- data/yard-stubs/carray_copy.rb +79 -0
- data/yard-stubs/carray_core.rb +34 -0
- data/yard-stubs/carray_count.rb +84 -0
- data/yard-stubs/carray_element.rb +108 -0
- data/yard-stubs/carray_generate.rb +66 -0
- data/yard-stubs/carray_lazy.rb +228 -0
- data/yard-stubs/carray_loop.rb +140 -0
- data/yard-stubs/carray_mask.rb +259 -0
- data/yard-stubs/carray_math.rb +1615 -0
- data/yard-stubs/carray_mathfunc.rb +45 -0
- data/yard-stubs/carray_median_percentile.rb +103 -0
- data/yard-stubs/carray_memory_view.rb +163 -0
- data/yard-stubs/carray_order.rb +252 -0
- data/yard-stubs/carray_random.rb +89 -0
- data/yard-stubs/carray_scatter.rb +106 -0
- data/yard-stubs/carray_slab.rb +59 -0
- data/yard-stubs/carray_sort.rb +165 -0
- data/yard-stubs/carray_test.rb +85 -0
- data/yard-stubs/carray_undef.rb +64 -0
- data/yard-stubs/carray_utils.rb +97 -0
- data/yard-stubs/ruby_carray.rb +193 -0
- metadata +67 -10
- data/ext/ca_obj_unbound_repeat.c +0 -496
data/ext/carray_call_cfunc.h
CHANGED
|
@@ -16,6 +16,18 @@
|
|
|
16
16
|
#ifndef CARRAY_CALL_CFUNC_H
|
|
17
17
|
#define CARRAY_CALL_CFUNC_H
|
|
18
18
|
|
|
19
|
+
/* Chunk callback for the ca_call_cslab_N family. `base` and `stride` are
|
|
20
|
+
one entry per operand, in the order the operands were passed; `n` is the
|
|
21
|
+
number of cells in this chunk; `m0` is the chunk's slice of the mask,
|
|
22
|
+
one byte per cell, or NULL when no INPUT carried a mask. The arity does
|
|
23
|
+
not appear in the signature -- the operands arrive through `base` -- so
|
|
24
|
+
one typedef serves every arity. */
|
|
25
|
+
typedef void (*ca_cslab_t) (char **base, ca_size_t *stride, ca_size_t n,
|
|
26
|
+
const boolean8_t *m0);
|
|
27
|
+
|
|
28
|
+
typedef void (*ca_cslab_r_t) (char **base, ca_size_t *stride, ca_size_t n,
|
|
29
|
+
const boolean8_t *m0, void *userdata);
|
|
30
|
+
|
|
19
31
|
VALUE
|
|
20
32
|
ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
|
|
21
33
|
VALUE rcx0);
|
|
@@ -157,4 +169,145 @@ ca_call_cfunc_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t
|
|
|
157
169
|
VALUE
|
|
158
170
|
ca_call_cfunc_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
159
171
|
|
|
172
|
+
VALUE
|
|
173
|
+
ca_call_cslab_1 (ca_cslab_t func, const char *fsync,
|
|
174
|
+
VALUE rcx0);
|
|
175
|
+
|
|
176
|
+
VALUE
|
|
177
|
+
ca_call_cslab_2 (ca_cslab_t func, const char *fsync,
|
|
178
|
+
VALUE rcx0, VALUE rcx1);
|
|
179
|
+
|
|
180
|
+
VALUE
|
|
181
|
+
ca_call_cslab_3 (ca_cslab_t func, const char *fsync,
|
|
182
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2);
|
|
183
|
+
|
|
184
|
+
VALUE
|
|
185
|
+
ca_call_cslab_4 (ca_cslab_t func, const char *fsync,
|
|
186
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3);
|
|
187
|
+
|
|
188
|
+
VALUE
|
|
189
|
+
ca_call_cslab_5 (ca_cslab_t func, const char *fsync,
|
|
190
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4);
|
|
191
|
+
|
|
192
|
+
VALUE
|
|
193
|
+
ca_call_cslab_6 (ca_cslab_t func, const char *fsync,
|
|
194
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5);
|
|
195
|
+
|
|
196
|
+
VALUE
|
|
197
|
+
ca_call_cslab_7 (ca_cslab_t func, const char *fsync,
|
|
198
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6);
|
|
199
|
+
|
|
200
|
+
VALUE
|
|
201
|
+
ca_call_cslab_1_r (ca_cslab_r_t func, const char *fsync,
|
|
202
|
+
VALUE rcx0,
|
|
203
|
+
void *userdata);
|
|
204
|
+
|
|
205
|
+
VALUE
|
|
206
|
+
ca_call_cslab_2_r (ca_cslab_r_t func, const char *fsync,
|
|
207
|
+
VALUE rcx0, VALUE rcx1,
|
|
208
|
+
void *userdata);
|
|
209
|
+
|
|
210
|
+
VALUE
|
|
211
|
+
ca_call_cslab_3_r (ca_cslab_r_t func, const char *fsync,
|
|
212
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2,
|
|
213
|
+
void *userdata);
|
|
214
|
+
|
|
215
|
+
VALUE
|
|
216
|
+
ca_call_cslab_4_r (ca_cslab_r_t func, const char *fsync,
|
|
217
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3,
|
|
218
|
+
void *userdata);
|
|
219
|
+
|
|
220
|
+
VALUE
|
|
221
|
+
ca_call_cslab_5_r (ca_cslab_r_t func, const char *fsync,
|
|
222
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4,
|
|
223
|
+
void *userdata);
|
|
224
|
+
|
|
225
|
+
VALUE
|
|
226
|
+
ca_call_cslab_6_r (ca_cslab_r_t func, const char *fsync,
|
|
227
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5,
|
|
228
|
+
void *userdata);
|
|
229
|
+
|
|
230
|
+
VALUE
|
|
231
|
+
ca_call_cslab_7_r (ca_cslab_r_t func, const char *fsync,
|
|
232
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6,
|
|
233
|
+
void *userdata);
|
|
234
|
+
|
|
235
|
+
VALUE
|
|
236
|
+
ca_call_cslab_1_1 (int8_t dty, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1);
|
|
237
|
+
|
|
238
|
+
VALUE
|
|
239
|
+
ca_call_cslab_1_2 (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2);
|
|
240
|
+
|
|
241
|
+
VALUE
|
|
242
|
+
ca_call_cslab_1_3 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3);
|
|
243
|
+
|
|
244
|
+
VALUE
|
|
245
|
+
ca_call_cslab_1_4 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4);
|
|
246
|
+
|
|
247
|
+
VALUE
|
|
248
|
+
ca_call_cslab_1_5 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5);
|
|
249
|
+
|
|
250
|
+
VALUE
|
|
251
|
+
ca_call_cslab_1_6 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6);
|
|
252
|
+
|
|
253
|
+
VALUE
|
|
254
|
+
ca_call_cslab_2_1 (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1);
|
|
255
|
+
|
|
256
|
+
VALUE
|
|
257
|
+
ca_call_cslab_2_2 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2);
|
|
258
|
+
|
|
259
|
+
VALUE
|
|
260
|
+
ca_call_cslab_2_3 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3);
|
|
261
|
+
|
|
262
|
+
VALUE
|
|
263
|
+
ca_call_cslab_2_4 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4);
|
|
264
|
+
|
|
265
|
+
VALUE
|
|
266
|
+
ca_call_cslab_3_1 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1);
|
|
267
|
+
|
|
268
|
+
VALUE
|
|
269
|
+
ca_call_cslab_3_2 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2);
|
|
270
|
+
|
|
271
|
+
VALUE
|
|
272
|
+
ca_call_cslab_3_3 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3);
|
|
273
|
+
|
|
274
|
+
VALUE
|
|
275
|
+
ca_call_cslab_1_1_r (int8_t dty, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata);
|
|
276
|
+
|
|
277
|
+
VALUE
|
|
278
|
+
ca_call_cslab_1_2_r (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata);
|
|
279
|
+
|
|
280
|
+
VALUE
|
|
281
|
+
ca_call_cslab_1_3_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
282
|
+
|
|
283
|
+
VALUE
|
|
284
|
+
ca_call_cslab_1_4_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata);
|
|
285
|
+
|
|
286
|
+
VALUE
|
|
287
|
+
ca_call_cslab_1_5_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, void *userdata);
|
|
288
|
+
|
|
289
|
+
VALUE
|
|
290
|
+
ca_call_cslab_1_6_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6, void *userdata);
|
|
291
|
+
|
|
292
|
+
VALUE
|
|
293
|
+
ca_call_cslab_2_1_r (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata);
|
|
294
|
+
|
|
295
|
+
VALUE
|
|
296
|
+
ca_call_cslab_2_2_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata);
|
|
297
|
+
|
|
298
|
+
VALUE
|
|
299
|
+
ca_call_cslab_2_3_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
300
|
+
|
|
301
|
+
VALUE
|
|
302
|
+
ca_call_cslab_2_4_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata);
|
|
303
|
+
|
|
304
|
+
VALUE
|
|
305
|
+
ca_call_cslab_3_1_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata);
|
|
306
|
+
|
|
307
|
+
VALUE
|
|
308
|
+
ca_call_cslab_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata);
|
|
309
|
+
|
|
310
|
+
VALUE
|
|
311
|
+
ca_call_cslab_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
312
|
+
|
|
160
313
|
#endif /* CARRAY_CALL_CFUNC_H */
|
data/ext/carray_cast.c
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Cast surface (3 layers):
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
of the target
|
|
7
|
-
`self`.
|
|
5
|
+
<type> `a.int32` etc., and the general `a.to_type(:int32)`.
|
|
6
|
+
Returns a fresh entity CArray of the target
|
|
7
|
+
data_type. Independent storage from `self`. (The
|
|
8
|
+
C functions are named rb_ca_to_<type>, but the
|
|
9
|
+
methods they register carry no `to_` prefix.)
|
|
8
10
|
|
|
9
11
|
as_<type> `a.as_int32` etc. Returns a writable CAMonOp view
|
|
10
12
|
that reinterprets `self` cell-by-cell at the target
|
|
@@ -550,6 +552,77 @@ rb_ca_object_to_data_class (VALUE self, VALUE rtype, ca_size_t bytes)
|
|
|
550
552
|
return obj;
|
|
551
553
|
}
|
|
552
554
|
|
|
555
|
+
typedef struct {
|
|
556
|
+
CArray *ca;
|
|
557
|
+
CArray *cb;
|
|
558
|
+
boolean8_t *scratch;
|
|
559
|
+
} ca_to_type_ctx_t;
|
|
560
|
+
|
|
561
|
+
/* The cast proper, with `ca` attached. It can raise (a value the target
|
|
562
|
+
type cannot hold), so it runs under rb_ensure. */
|
|
563
|
+
static VALUE
|
|
564
|
+
ca_to_type_cast (VALUE arg)
|
|
565
|
+
{
|
|
566
|
+
ca_to_type_ctx_t *c = (ca_to_type_ctx_t *) arg;
|
|
567
|
+
CArray *ca = c->ca, *cb = c->cb;
|
|
568
|
+
|
|
569
|
+
if ( ca->data_type == CA_OBJECT
|
|
570
|
+
&& ( (cb->data_type >= CA_INT8 && cb->data_type <= CA_UINT64)
|
|
571
|
+
|| cb->data_type == CA_FLOAT32 || cb->data_type == CA_FLOAT64 ) ) {
|
|
572
|
+
/* object -> int/float: give the cast a mask buffer so an unparseable
|
|
573
|
+
cell becomes UNDEF (see ext/carray_cast_func.rb). Cast into a
|
|
574
|
+
scratch mask seeded from the source mask, then attach it to the
|
|
575
|
+
output only if some cell ended up masked -- an all-valid cast keeps
|
|
576
|
+
the mask-less result the legacy path produced. */
|
|
577
|
+
ca_size_t ne = cb->elements;
|
|
578
|
+
ca_size_t i;
|
|
579
|
+
boolean8_t any = 0;
|
|
580
|
+
boolean8_t *scratch;
|
|
581
|
+
c->scratch = scratch = ALLOC_N(boolean8_t, ne > 0 ? ne : 1);
|
|
582
|
+
if ( cb->mask ) {
|
|
583
|
+
memcpy(scratch, cb->mask->ptr, ne); /* copy of source mask */
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
memset(scratch, 0, ne);
|
|
587
|
+
}
|
|
588
|
+
ca_cast_block_with_mask(ne, ca, ca->ptr, cb, cb->ptr, scratch);
|
|
589
|
+
for (i=0; i<ne; i++) {
|
|
590
|
+
if ( scratch[i] ) {
|
|
591
|
+
any = 1;
|
|
592
|
+
break;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if ( any ) {
|
|
596
|
+
if ( ! cb->mask ) {
|
|
597
|
+
ca_create_mask(cb);
|
|
598
|
+
}
|
|
599
|
+
memcpy(cb->mask->ptr, scratch, ne);
|
|
600
|
+
}
|
|
601
|
+
xfree(scratch);
|
|
602
|
+
c->scratch = NULL;
|
|
603
|
+
}
|
|
604
|
+
else if ( ca_has_mask(ca) ) {
|
|
605
|
+
ca_cast_block_with_mask(cb->elements, ca, ca->ptr, cb, cb->ptr,
|
|
606
|
+
(boolean8_t*)ca->mask->ptr);
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
ca_cast_block(cb->elements, ca, ca->ptr, cb, cb->ptr);
|
|
610
|
+
}
|
|
611
|
+
return Qnil;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
static VALUE
|
|
615
|
+
ca_to_type_release (VALUE arg)
|
|
616
|
+
{
|
|
617
|
+
ca_to_type_ctx_t *c = (ca_to_type_ctx_t *) arg;
|
|
618
|
+
if ( c->scratch ) {
|
|
619
|
+
xfree(c->scratch);
|
|
620
|
+
c->scratch = NULL;
|
|
621
|
+
}
|
|
622
|
+
ca_detach(c->ca);
|
|
623
|
+
return Qnil;
|
|
624
|
+
}
|
|
625
|
+
|
|
553
626
|
/* CArray#to_type(data_type, bytes:) -- eager copy of self converted to
|
|
554
627
|
data_type (a new entity owning its storage). User doc lives in
|
|
555
628
|
yard-stubs/carray_cast.rb. */
|
|
@@ -559,6 +632,7 @@ rb_ca_to_type_internal (int argc, VALUE *argv, VALUE self)
|
|
|
559
632
|
{
|
|
560
633
|
volatile VALUE obj, rtype = Qnil, ropt, rbytes = Qnil;
|
|
561
634
|
CArray *ca, *cb;
|
|
635
|
+
ca_to_type_ctx_t ctx;
|
|
562
636
|
int8_t data_type;
|
|
563
637
|
ca_size_t bytes;
|
|
564
638
|
|
|
@@ -599,48 +673,11 @@ rb_ca_to_type_internal (int argc, VALUE *argv, VALUE self)
|
|
|
599
673
|
|
|
600
674
|
TypedData_Get_Struct(obj, CArray, &carray_data_type, cb);
|
|
601
675
|
|
|
676
|
+
ctx.ca = ca;
|
|
677
|
+
ctx.cb = cb;
|
|
678
|
+
ctx.scratch = NULL;
|
|
602
679
|
ca_attach(ca);
|
|
603
|
-
|
|
604
|
-
&& ( (data_type >= CA_INT8 && data_type <= CA_UINT64)
|
|
605
|
-
|| data_type == CA_FLOAT32 || data_type == CA_FLOAT64 ) ) {
|
|
606
|
-
/* object -> int/float: give the cast a mask buffer so an unparseable
|
|
607
|
-
cell becomes UNDEF (see ext/carray_cast_func.rb). Cast into a
|
|
608
|
-
scratch mask seeded from the source mask, then attach it to the
|
|
609
|
-
output only if some cell ended up masked -- an all-valid cast keeps
|
|
610
|
-
the mask-less result the legacy path produced. */
|
|
611
|
-
ca_size_t ne = cb->elements;
|
|
612
|
-
ca_size_t i;
|
|
613
|
-
boolean8_t any = 0;
|
|
614
|
-
boolean8_t *scratch = ALLOC_N(boolean8_t, ne > 0 ? ne : 1);
|
|
615
|
-
if ( cb->mask ) {
|
|
616
|
-
memcpy(scratch, cb->mask->ptr, ne); /* copy of source mask */
|
|
617
|
-
}
|
|
618
|
-
else {
|
|
619
|
-
memset(scratch, 0, ne);
|
|
620
|
-
}
|
|
621
|
-
ca_cast_block_with_mask(ne, ca, ca->ptr, cb, cb->ptr, scratch);
|
|
622
|
-
for (i=0; i<ne; i++) {
|
|
623
|
-
if ( scratch[i] ) {
|
|
624
|
-
any = 1;
|
|
625
|
-
break;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
if ( any ) {
|
|
629
|
-
if ( ! cb->mask ) {
|
|
630
|
-
ca_create_mask(cb);
|
|
631
|
-
}
|
|
632
|
-
memcpy(cb->mask->ptr, scratch, ne);
|
|
633
|
-
}
|
|
634
|
-
xfree(scratch);
|
|
635
|
-
}
|
|
636
|
-
else if ( ca_has_mask(ca) ) {
|
|
637
|
-
ca_cast_block_with_mask(cb->elements, ca, ca->ptr, cb, cb->ptr,
|
|
638
|
-
(boolean8_t*)ca->mask->ptr);
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
ca_cast_block(cb->elements, ca, ca->ptr, cb, cb->ptr);
|
|
642
|
-
}
|
|
643
|
-
ca_detach(ca);
|
|
680
|
+
rb_ensure(ca_to_type_cast, (VALUE) &ctx, ca_to_type_release, (VALUE) &ctx);
|
|
644
681
|
|
|
645
682
|
/* When rtype is a data_class (e.g. CAStruct subclass), wrap the
|
|
646
683
|
result in CARecord so the cast output carries data_class. */
|
|
@@ -773,16 +810,62 @@ extern VALUE rb_ca_monop_build (VALUE cary, uint16_t op_id);
|
|
|
773
810
|
/* Forward declaration: clip kernel (ext/carray_kernels.c, generated). */
|
|
774
811
|
extern VALUE rb_ca_clip (VALUE self, VALUE lo, VALUE hi);
|
|
775
812
|
|
|
813
|
+
/* Which surface asked for a type-adapt view. A Face's cells do not mean
|
|
814
|
+
their storage bytes and there is no view that decodes them, so each
|
|
815
|
+
caller says what it does instead of reinterpreting the storage. */
|
|
816
|
+
enum {
|
|
817
|
+
CA_ADAPT_VIEW, /* as_type: the values are behind #to_type */
|
|
818
|
+
CA_ADAPT_READONLY, /* wrap_readonly: the eager conversion is the answer */
|
|
819
|
+
CA_ADAPT_WRITABLE /* wrap_writable: writes have nowhere to land */
|
|
820
|
+
};
|
|
821
|
+
|
|
776
822
|
/* Routes a type-adapt view request to CAMonOp(cast_<dt>) when the
|
|
777
823
|
target is a plain numeric data_type (NOT CA_FIXLEN, NOT CA_OBJECT,
|
|
778
824
|
and `rtype` is not a Class). Falls back to CAFake
|
|
779
825
|
(`rb_ca_fake_type`) for CA_FIXLEN sizing, CA_OBJECT, and class-rtype
|
|
780
826
|
data_class overlay cases.
|
|
781
827
|
Called by rb_ca_as_type_internal, rb_ca_wrap_readonly, and
|
|
782
|
-
rb_ca_wrap_writable in this file.
|
|
828
|
+
rb_ca_wrap_writable in this file.
|
|
829
|
+
|
|
830
|
+
A Face whose surface is not its storage reaches neither: reinterpreting
|
|
831
|
+
the storage would hand back the bytes the surface exists to hide (the
|
|
832
|
+
serial instead of the time, the descriptor instead of the string).
|
|
833
|
+
wrap_readonly, which already returns entities for its non-CArray inputs,
|
|
834
|
+
answers with the eager conversion #to_type performs -- the surface values,
|
|
835
|
+
or the Face's own #to_numeric for a numeric target. as_type and
|
|
836
|
+
wrap_writable have no honest answer and say so. */
|
|
783
837
|
static VALUE
|
|
784
|
-
ca_type_adapt_view (VALUE obj, VALUE rtype, int8_t data_type)
|
|
838
|
+
ca_type_adapt_view (VALUE obj, VALUE rtype, int8_t data_type, int mode)
|
|
785
839
|
{
|
|
840
|
+
CArray *ca;
|
|
841
|
+
|
|
842
|
+
TypedData_Get_Struct(obj, CArray, &carray_data_type, ca);
|
|
843
|
+
|
|
844
|
+
/* Same split the eager cast makes: :object is the Face's surface for every
|
|
845
|
+
Face, and a NonNumeric Face (CA_FIXLEN surface) has no reading of its
|
|
846
|
+
storage as a number either. A Numeric Face falls through, because there
|
|
847
|
+
its surface *is* its storage and the ordinary cast below is right. */
|
|
848
|
+
if ( ca_is_face(ca) && ( data_type == CA_OBJECT
|
|
849
|
+
|| ca->data_type == CA_FIXLEN ) ) {
|
|
850
|
+
VALUE args[1];
|
|
851
|
+
switch ( mode ) {
|
|
852
|
+
case CA_ADAPT_READONLY:
|
|
853
|
+
args[0] = rtype;
|
|
854
|
+
return rb_ca_to_type_internal(1, args, obj);
|
|
855
|
+
case CA_ADAPT_WRITABLE:
|
|
856
|
+
rb_raise(rb_eTypeError,
|
|
857
|
+
"%s has no writable view in another data_type: the writes "
|
|
858
|
+
"would land on the storage its surface hides -- wrap "
|
|
859
|
+
"#parent to reach that storage",
|
|
860
|
+
rb_obj_classname(obj));
|
|
861
|
+
default:
|
|
862
|
+
rb_raise(rb_eTypeError,
|
|
863
|
+
"%s has no view of its values in another data_type: "
|
|
864
|
+
"#to_type gives the values, #parent the raw storage",
|
|
865
|
+
rb_obj_classname(obj));
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
786
869
|
if ( data_type != CA_FIXLEN
|
|
787
870
|
&& data_type != CA_OBJECT
|
|
788
871
|
&& TYPE(rtype) != T_CLASS ) {
|
|
@@ -815,7 +898,7 @@ rb_ca_as_type_internal (int argc, VALUE *argv, VALUE self)
|
|
|
815
898
|
/* Natural-width cast: dispatch via helper (CAMonOp for numeric,
|
|
816
899
|
CAFake for CA_FIXLEN sizing / CA_OBJECT / class-rtype). */
|
|
817
900
|
if ( bytes == (ca_size_t) ca_sizeof[data_type] ) {
|
|
818
|
-
obj = ca_type_adapt_view(self, rtype, data_type);
|
|
901
|
+
obj = ca_type_adapt_view(self, rtype, data_type, CA_ADAPT_VIEW);
|
|
819
902
|
return obj;
|
|
820
903
|
}
|
|
821
904
|
|
|
@@ -1075,7 +1158,7 @@ rb_ca_wrap_writable (VALUE arg, VALUE rtype)
|
|
|
1075
1158
|
data_type = rb_ca_guess_type(rtype);
|
|
1076
1159
|
}
|
|
1077
1160
|
if ( ca->data_type != data_type ) {
|
|
1078
|
-
obj = ca_type_adapt_view(obj, rtype, data_type);
|
|
1161
|
+
obj = ca_type_adapt_view(obj, rtype, data_type, CA_ADAPT_WRITABLE);
|
|
1079
1162
|
}
|
|
1080
1163
|
}
|
|
1081
1164
|
else if ( NIL_P(obj) ) { /* obj == nil */
|
|
@@ -1113,7 +1196,8 @@ rb_ca_wrap_writable (VALUE arg, VALUE rtype)
|
|
|
1113
1196
|
data_type = rb_ca_guess_type(rtype);
|
|
1114
1197
|
}
|
|
1115
1198
|
if ( ca->data_type != data_type ) {
|
|
1116
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1199
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1200
|
+
CA_ADAPT_WRITABLE);
|
|
1117
1201
|
}
|
|
1118
1202
|
}
|
|
1119
1203
|
else if ( rb_memory_view_available_p(obj) ) { /* MemoryView producer */
|
|
@@ -1130,7 +1214,8 @@ rb_ca_wrap_writable (VALUE arg, VALUE rtype)
|
|
|
1130
1214
|
data_type = rb_ca_guess_type(rtype);
|
|
1131
1215
|
}
|
|
1132
1216
|
if ( ca->data_type != data_type ) {
|
|
1133
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1217
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1218
|
+
CA_ADAPT_WRITABLE);
|
|
1134
1219
|
}
|
|
1135
1220
|
}
|
|
1136
1221
|
else {
|
|
@@ -1171,7 +1256,7 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1171
1256
|
data_type = rb_ca_guess_type(rtype);
|
|
1172
1257
|
}
|
|
1173
1258
|
if ( ca->data_type != data_type ) {
|
|
1174
|
-
obj = ca_type_adapt_view(obj, rtype, data_type);
|
|
1259
|
+
obj = ca_type_adapt_view(obj, rtype, data_type, CA_ADAPT_READONLY);
|
|
1175
1260
|
}
|
|
1176
1261
|
}
|
|
1177
1262
|
else if ( rb_obj_is_kind_of(obj, rb_cNumeric) ) { /* number */
|
|
@@ -1193,7 +1278,8 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1193
1278
|
data_type = rb_ca_guess_type(rtype);
|
|
1194
1279
|
}
|
|
1195
1280
|
if ( ca->data_type != data_type ) {
|
|
1196
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1281
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1282
|
+
CA_ADAPT_READONLY);
|
|
1197
1283
|
}
|
|
1198
1284
|
}
|
|
1199
1285
|
else if ( TYPE(obj) == T_STRING ) { /* string */
|
|
@@ -1234,7 +1320,8 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1234
1320
|
data_type = rb_ca_guess_type(rtype);
|
|
1235
1321
|
}
|
|
1236
1322
|
if ( ca->data_type != data_type ) {
|
|
1237
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1323
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1324
|
+
CA_ADAPT_READONLY);
|
|
1238
1325
|
}
|
|
1239
1326
|
}
|
|
1240
1327
|
else if ( rb_memory_view_available_p(obj) ) { /* MemoryView producer */
|
|
@@ -1247,7 +1334,8 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1247
1334
|
data_type = rb_ca_guess_type(rtype);
|
|
1248
1335
|
}
|
|
1249
1336
|
if ( ca->data_type != data_type ) {
|
|
1250
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1337
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1338
|
+
CA_ADAPT_READONLY);
|
|
1251
1339
|
}
|
|
1252
1340
|
}
|
|
1253
1341
|
else { /* object */
|
|
@@ -1313,6 +1401,36 @@ rb_ca_cast (volatile VALUE self)
|
|
|
1313
1401
|
return obj;
|
|
1314
1402
|
}
|
|
1315
1403
|
|
|
1404
|
+
/* A String operand against a fixlen array is a value of that array's cell
|
|
1405
|
+
width. ca_value_to_data_type answers CA_OBJECT for a String, so without
|
|
1406
|
+
this the operand became an object scalar and the comparison ran down the
|
|
1407
|
+
object lane -- an rb_funcall of String#== per cell, against the cell's
|
|
1408
|
+
NUL-padded text. A fixlen array pads a short String on write
|
|
1409
|
+
(`a[i] = "be"` stores "be\0\0\0"), so that answered that an array does
|
|
1410
|
+
not equal the string it was written from, and did it 30x slower than the
|
|
1411
|
+
memcmp lane the fixlen comparison bodies are there to provide.
|
|
1412
|
+
|
|
1413
|
+
Two fixlen *arrays* of different widths keep the variable-width byte
|
|
1414
|
+
string semantics those bodies implement (min-width memcmp with a length
|
|
1415
|
+
tiebreak); this is only about a scalar standing in for a cell. */
|
|
1416
|
+
static int
|
|
1417
|
+
ca_fixlen_scalar_operand (volatile VALUE *scalar, VALUE reference)
|
|
1418
|
+
{
|
|
1419
|
+
CArray *cr;
|
|
1420
|
+
/* A String is the only operand that means a cell value here. A Regexp
|
|
1421
|
+
(match) or any other object keeps its own coercion: those are asking
|
|
1422
|
+
something about the bytes, not standing in for them. */
|
|
1423
|
+
if ( ! RB_TYPE_P(*scalar, T_STRING) || ! rb_obj_is_carray(reference) ) {
|
|
1424
|
+
return 0;
|
|
1425
|
+
}
|
|
1426
|
+
TypedData_Get_Struct(reference, CArray, &carray_data_type, cr);
|
|
1427
|
+
if ( cr->data_type != CA_FIXLEN ) {
|
|
1428
|
+
return 0;
|
|
1429
|
+
}
|
|
1430
|
+
*scalar = rb_cscalar_new_with_value(CA_FIXLEN, cr->bytes, *scalar);
|
|
1431
|
+
return 1;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1316
1434
|
/* CArray.cast(value) -- singleton entry delegating to rb_ca_cast, which
|
|
1317
1435
|
returns a CArray unchanged and coerces a Ruby value to a CScalar / CArray.
|
|
1318
1436
|
User doc lives in yard-stubs/carray_cast.rb. */
|
|
@@ -1356,6 +1474,9 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
1356
1474
|
*self = rb_cscalar_new_with_value(CA_CMPLX128, 0, *self);
|
|
1357
1475
|
}
|
|
1358
1476
|
#endif
|
|
1477
|
+
else if ( ca_fixlen_scalar_operand(self, *other) ) {
|
|
1478
|
+
/* width taken from the fixlen reference; see the helper above */
|
|
1479
|
+
}
|
|
1359
1480
|
else if ( rb_ca_is_float_type(*other) ) {
|
|
1360
1481
|
*self = rb_cscalar_new_with_value(CA_FLOAT64, 0, *self);
|
|
1361
1482
|
}
|
|
@@ -1384,6 +1505,9 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
1384
1505
|
*other = rb_cscalar_new_with_value(CA_CMPLX128, 0, *other);
|
|
1385
1506
|
}
|
|
1386
1507
|
#endif
|
|
1508
|
+
else if ( ca_fixlen_scalar_operand(other, *self) ) {
|
|
1509
|
+
/* width taken from the fixlen reference; see the helper above */
|
|
1510
|
+
}
|
|
1387
1511
|
else if ( rb_ca_is_float_type(*self) ) {
|
|
1388
1512
|
*other = rb_cscalar_new_with_value(CA_FLOAT64, 0, *other);
|
|
1389
1513
|
}
|
|
@@ -1400,16 +1524,6 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
1400
1524
|
TypedData_Get_Struct(*self, CArray, &carray_data_type, ca);
|
|
1401
1525
|
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1402
1526
|
|
|
1403
|
-
if ( ca->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
|
|
1404
|
-
*self = ca_ubrep_bind_with(*self, *other);
|
|
1405
|
-
TypedData_Get_Struct(*self, CArray, &carray_data_type, ca);
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
if ( cb->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
|
|
1409
|
-
*other = ca_ubrep_bind_with(*other, *self);
|
|
1410
|
-
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
1527
|
/* Implicit size-1 broadcasting (case A only). No-op if either side
|
|
1414
1528
|
is scalar, ndim differs, or shapes are already equal. If shapes
|
|
1415
1529
|
are incompatible (neither side is 1 nor equal on some axis), also
|
|
@@ -1781,6 +1895,9 @@ rb_ca_cast_other (VALUE *self, volatile VALUE *other)
|
|
|
1781
1895
|
if ( rb_ca_is_object_type(*self) ) {
|
|
1782
1896
|
*other = rb_cscalar_new_with_value(CA_OBJECT, 0, *other);
|
|
1783
1897
|
}
|
|
1898
|
+
else if ( ca_fixlen_scalar_operand(other, *self) ) {
|
|
1899
|
+
return; /* already the receiver's data_type and width */
|
|
1900
|
+
}
|
|
1784
1901
|
else if ( rb_ca_is_float_type(*self) ) {
|
|
1785
1902
|
*other = rb_cscalar_new_with_value(CA_FLOAT64, 0, *other);
|
|
1786
1903
|
}
|
|
@@ -1806,11 +1923,6 @@ rb_ca_cast_other (VALUE *self, volatile VALUE *other)
|
|
|
1806
1923
|
|
|
1807
1924
|
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1808
1925
|
|
|
1809
|
-
if ( cb->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
|
|
1810
|
-
*other = ca_ubrep_bind_with(*other, *self);
|
|
1811
|
-
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
1926
|
test1 = ca_cast_table[cb->data_type][ca->data_type];
|
|
1815
1927
|
|
|
1816
1928
|
if ( test1 == 0 ) {
|
|
@@ -1845,8 +1957,8 @@ rb_ca_cast_with (VALUE self, VALUE other)
|
|
|
1845
1957
|
}
|
|
1846
1958
|
|
|
1847
1959
|
/* -----------------------------------------------------------------------
|
|
1848
|
-
clip_<
|
|
1849
|
-
range, then cast. Sugar for `clip(lo, hi).as_<
|
|
1960
|
+
clip_<type> family — clip into the target data type's representable
|
|
1961
|
+
range, then cast. Sugar for `clip(lo, hi).as_<type>`.
|
|
1850
1962
|
----------------------------------------------------------------------- */
|
|
1851
1963
|
|
|
1852
1964
|
#define CLIP_CAST_FUNC(name, lo_expr, hi_expr, cast_func) \
|
|
@@ -1873,7 +1985,7 @@ CLIP_CAST_FUNC(clip_uint32, INT2NUM(0), UINT2NUM(429496729
|
|
|
1873
1985
|
an overflowing float source (e.g. 1e20) to 2^64 and the subsequent cast to
|
|
1874
1986
|
uint64 wraps around to 0. For floating-point sources we take a saturating
|
|
1875
1987
|
path: compare in float space against 2^64 (which IS representable) and
|
|
1876
|
-
saturate to UINT64_MAX above it and 0 below zero. Other source
|
|
1988
|
+
saturate to UINT64_MAX above it and 0 below zero. Other source data types use
|
|
1877
1989
|
the plain clip-then-cast path. */
|
|
1878
1990
|
static VALUE
|
|
1879
1991
|
rb_ca_clip_uint64 (VALUE self)
|