carray 3.0.2 → 3.0.3
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/CHANGELOG.md +304 -0
- data/README.md +3 -4
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +225 -0
- data/ext/ca_axis_group.c +177 -99
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +66 -71
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +663 -214
- data/ext/ca_kernel_iterator.h +231 -167
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +132 -22
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +1 -0
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +96 -25
- data/ext/ca_obj_face.c +406 -64
- data/ext/ca_obj_face.h +92 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +21 -21
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +189 -107
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +543 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +47 -49
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -118
- data/ext/ca_obj_stride.c +195 -34
- data/ext/ca_obj_string.c +17 -18
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +149 -27
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +102 -79
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +70 -27
- data/ext/carray_access.c +455 -211
- data/ext/carray_address_basis.c +177 -36
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +46 -14
- data/ext/carray_call_cfunc.c +0 -28
- data/ext/carray_cast.c +1444 -209
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +32 -11
- data/ext/carray_core.c +514 -122
- data/ext/carray_count.c +140 -87
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +569 -277
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +385 -3
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +682 -316
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +221 -76
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1089 -359
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +273 -239
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +170 -70
- data/ext/carray_sort.c +215 -218
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +0 -2
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1076 -846
- data/ext/ruby_carray.c +7 -1
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +19 -0
- data/lib/carray/autoload_method_extension.rb +6 -0
- data/lib/carray/axis_group.rb +174 -26
- data/lib/carray/basics.rb +91 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +118 -48
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +94 -26
- data/lib/carray/categorical_iterator.rb +333 -826
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +46 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +589 -82
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +124 -25
- data/lib/carray/frame/group.rb +189 -63
- data/lib/carray/frame/io.rb +412 -72
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +37 -16
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +715 -48
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +29 -11
- data/lib/carray/iterator.rb +14 -2
- data/lib/carray/lazy.rb +54 -30
- data/lib/carray/mask_gap_fill.rb +66 -52
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +117 -4
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +177 -36
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +51 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +4 -3
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +517 -103
- data/lib/carray/window_iterator.rb +127 -72
- data/lib/carray.rb +2 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +1 -2
- data/yard-stubs/carray_access.rb +5 -4
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +25 -13
- data/yard-stubs/carray_median_percentile.rb +10 -6
- data/yard-stubs/carray_order.rb +34 -13
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +2 -1
- data/yard-stubs/carray_sort.rb +43 -3
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +11 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -26005
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14862
- data/ext/carray_kernels_reduce_extreme.c +0 -17494
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32218
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/carray_utils.c
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
Utility helpers shared across the `ext/` C files: iterator setup / loop count
|
|
4
4
|
variadic helpers, Range parsing (`ca_parse_range` family), axis
|
|
5
5
|
normalization primitives (`ca_normalize_axis*` + Ruby-facing
|
|
6
|
-
`normalize_axis` / `normalize_axes`)
|
|
7
|
-
(`_scan_float` / `_scan_int`) for the text I/O layer.
|
|
6
|
+
`normalize_axis` / `normalize_axes`).
|
|
8
7
|
|
|
9
8
|
YARD signatures live in yard-stubs/carray_utils.rb; this file
|
|
10
9
|
carries implementation-only prose.
|
|
@@ -14,8 +13,10 @@
|
|
|
14
13
|
#include <stdarg.h>
|
|
15
14
|
#include "ruby.h"
|
|
16
15
|
#include "carray.h"
|
|
16
|
+
#include "carray_internal.h" /* ca_calling_method_name */
|
|
17
17
|
|
|
18
18
|
#include "ruby/st.h"
|
|
19
|
+
#include "ruby/thread_native.h"
|
|
19
20
|
|
|
20
21
|
static ID id_begin, id_end, id_excl_end;
|
|
21
22
|
#define RANGE_BEG(r) (rb_funcall(r, id_begin, 0))
|
|
@@ -55,7 +56,7 @@ ca_set_iterator (int n, ...)
|
|
|
55
56
|
max = ca->elements;
|
|
56
57
|
}
|
|
57
58
|
else if ( max != ca->elements ) {
|
|
58
|
-
rb_raise(
|
|
59
|
+
rb_raise(rb_eArgError, "data size mismatch in operation");
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -94,7 +95,7 @@ ca_get_loop_count (int n, ...)
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
if ( elements == -1 ) {
|
|
97
|
-
rb_raise(
|
|
98
|
+
rb_raise(rb_eArgError, "no data to process");
|
|
98
99
|
}
|
|
99
100
|
return elements;
|
|
100
101
|
}
|
|
@@ -153,8 +154,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
153
154
|
last += ( (last>=start) ? -1 : 1 );
|
|
154
155
|
}
|
|
155
156
|
if ( last < 0 || last >= size ) {
|
|
156
|
-
|
|
157
|
-
"invalid index range");
|
|
157
|
+
ca_index_out_of_range(last, size, "index");
|
|
158
158
|
}
|
|
159
159
|
*poffset = start;
|
|
160
160
|
*pcount = llabs(last - start) + 1;
|
|
@@ -170,7 +170,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
170
170
|
excl = RTEST(x.exclude_end);
|
|
171
171
|
step = NUM2SIZE(x.step);
|
|
172
172
|
if ( step == 0 ) {
|
|
173
|
-
rb_raise(
|
|
173
|
+
rb_raise(rb_eArgError, "step should not be 0");
|
|
174
174
|
}
|
|
175
175
|
if ( last < 0 ) {
|
|
176
176
|
last += size;
|
|
@@ -179,7 +179,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
179
179
|
last += ( (last>=start) ? -1 : 1 );
|
|
180
180
|
}
|
|
181
181
|
if ( last < 0 || last >= size ) {
|
|
182
|
-
|
|
182
|
+
ca_index_out_of_range(last, size, "index");
|
|
183
183
|
}
|
|
184
184
|
CA_CHECK_INDEX(start, size);
|
|
185
185
|
if ( (last - start) * step < 0 ) {
|
|
@@ -206,7 +206,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
206
206
|
if ( NIL_P(arg0) ) { /* [nil,k] */
|
|
207
207
|
step = NUM2SIZE(arg1);
|
|
208
208
|
if ( step == 0 ) {
|
|
209
|
-
rb_raise(
|
|
209
|
+
rb_raise(rb_eArgError, "step should not be 0");
|
|
210
210
|
}
|
|
211
211
|
start = 0;
|
|
212
212
|
count = (size-1)/llabs(step) + 1;
|
|
@@ -223,7 +223,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
223
223
|
excl = RTEST(RANGE_EXCL(arg0));
|
|
224
224
|
step = NUM2SIZE(arg1);
|
|
225
225
|
if ( step == 0 ) {
|
|
226
|
-
rb_raise(
|
|
226
|
+
rb_raise(rb_eArgError, "step should not be 0");
|
|
227
227
|
}
|
|
228
228
|
if ( last < 0 ) {
|
|
229
229
|
last += size;
|
|
@@ -232,7 +232,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
232
232
|
last += ( (last>=start) ? -1 : 1 );
|
|
233
233
|
}
|
|
234
234
|
if ( last < 0 || last >= size ) {
|
|
235
|
-
|
|
235
|
+
ca_index_out_of_range(last, size, "index");
|
|
236
236
|
}
|
|
237
237
|
CA_CHECK_INDEX(start, size);
|
|
238
238
|
if ( (last - start) * step < 0 ) {
|
|
@@ -257,7 +257,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
257
257
|
excl = RTEST(x.exclude_end);
|
|
258
258
|
step = NUM2SIZE(x.step);
|
|
259
259
|
if ( step == 0 ) {
|
|
260
|
-
rb_raise(
|
|
260
|
+
rb_raise(rb_eArgError, "step should not be 0");
|
|
261
261
|
}
|
|
262
262
|
if ( last < 0 ) {
|
|
263
263
|
last += size;
|
|
@@ -266,7 +266,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
266
266
|
last += ( (last>=start) ? -1 : 1 );
|
|
267
267
|
}
|
|
268
268
|
if ( last < 0 || last >= size ) {
|
|
269
|
-
|
|
269
|
+
ca_index_out_of_range(last, size, "index");
|
|
270
270
|
}
|
|
271
271
|
CA_CHECK_INDEX(start, size);
|
|
272
272
|
if ( (last - start) * step < 0 ) {
|
|
@@ -298,7 +298,7 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
298
298
|
count = NUM2SIZE(rb_ary_entry(arg, 1));
|
|
299
299
|
step = NUM2SIZE(rb_ary_entry(arg, 2));
|
|
300
300
|
if ( step == 0 ) {
|
|
301
|
-
rb_raise(
|
|
301
|
+
rb_raise(rb_eArgError, "step should not be 0");
|
|
302
302
|
}
|
|
303
303
|
bound = start + (count - 1)*step;
|
|
304
304
|
CA_CHECK_INDEX(start, size);
|
|
@@ -308,11 +308,11 @@ ca_parse_range (VALUE arg, ca_size_t size,
|
|
|
308
308
|
*pstep = step;
|
|
309
309
|
}
|
|
310
310
|
else {
|
|
311
|
-
rb_raise(
|
|
311
|
+
rb_raise(rb_eArgError, "unknown range specification");
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
else {
|
|
315
|
-
rb_raise(
|
|
315
|
+
rb_raise(rb_eArgError, "unknown range specification");
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
|
|
@@ -430,11 +430,11 @@ ca_parse_range_without_check (VALUE arg, ca_size_t size,
|
|
|
430
430
|
*pstep = step;
|
|
431
431
|
}
|
|
432
432
|
else {
|
|
433
|
-
rb_raise(
|
|
433
|
+
rb_raise(rb_eArgError, "unknown range specification");
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
436
|
else {
|
|
437
|
-
rb_raise(
|
|
437
|
+
rb_raise(rb_eArgError, "unknown range specification");
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
|
|
@@ -458,14 +458,12 @@ ca_bounds_normalize_index (int8_t bounds, ca_size_t size0, ca_size_t k)
|
|
|
458
458
|
k += size0;
|
|
459
459
|
}
|
|
460
460
|
if ( k < 0 || k >= size0 ) {
|
|
461
|
-
|
|
462
|
-
"window index out of range");
|
|
461
|
+
ca_index_out_of_range(k, size0, "index");
|
|
463
462
|
}
|
|
464
463
|
return k;
|
|
465
464
|
case CA_BOUNDS_STRICT:
|
|
466
465
|
if ( k < 0 || k >= size0 ) {
|
|
467
|
-
|
|
468
|
-
"window index out of range");
|
|
466
|
+
ca_index_out_of_range(k, size0, "index");
|
|
469
467
|
}
|
|
470
468
|
return k;
|
|
471
469
|
case CA_BOUNDS_NEAREST:
|
|
@@ -477,16 +475,332 @@ ca_bounds_normalize_index (int8_t bounds, ca_size_t size0, ca_size_t k)
|
|
|
477
475
|
k = k % (2*size0);
|
|
478
476
|
return ( k < size0 ) ? k : 2*size0-1-k;
|
|
479
477
|
default:
|
|
480
|
-
rb_raise(
|
|
478
|
+
rb_raise(rb_eArgError,
|
|
481
479
|
"unknown window boundary specified (%i)", bounds);
|
|
482
480
|
}
|
|
483
481
|
}
|
|
484
482
|
|
|
483
|
+
/* The name of the method the user called, for error messages. A C
|
|
484
|
+
entry reached directly from C (no rb_funcall) reports the method that
|
|
485
|
+
was entered from Ruby, which is the one the user wrote. The internal
|
|
486
|
+
`_ki` twin of a public method is reported under the public name.
|
|
487
|
+
Falls back to "axis" when there is no method frame. */
|
|
488
|
+
/* A C copy of an ID's name that stays put. rb_id2name points into the
|
|
489
|
+
name's String, which compaction can move while a caller is still
|
|
490
|
+
formatting a message with it; the copy is made once per ID while the
|
|
491
|
+
String is held on the stack (and so pinned), and kept for the life of
|
|
492
|
+
the process. The table is shared by every Ractor, hence the lock. */
|
|
493
|
+
static st_table *ca_id_names = NULL;
|
|
494
|
+
static rb_nativethread_lock_t ca_id_names_lock;
|
|
495
|
+
|
|
496
|
+
static const char *
|
|
497
|
+
ca_stable_id_name (ID id)
|
|
498
|
+
{
|
|
499
|
+
st_data_t found;
|
|
500
|
+
const char *name = NULL;
|
|
501
|
+
rb_nativethread_lock_lock(&ca_id_names_lock);
|
|
502
|
+
if ( st_lookup(ca_id_names, (st_data_t) id, &found) ) {
|
|
503
|
+
name = (const char *) found;
|
|
504
|
+
}
|
|
505
|
+
rb_nativethread_lock_unlock(&ca_id_names_lock);
|
|
506
|
+
if ( name ) {
|
|
507
|
+
return name;
|
|
508
|
+
}
|
|
509
|
+
{
|
|
510
|
+
VALUE str = rb_id2str(id);
|
|
511
|
+
long len;
|
|
512
|
+
char *copy;
|
|
513
|
+
if ( NIL_P(str) ) {
|
|
514
|
+
return NULL;
|
|
515
|
+
}
|
|
516
|
+
len = RSTRING_LEN(str);
|
|
517
|
+
copy = ALLOC_N(char, len + 1);
|
|
518
|
+
memcpy(copy, RSTRING_PTR(str), len);
|
|
519
|
+
copy[len] = '\0';
|
|
520
|
+
RB_GC_GUARD(str);
|
|
521
|
+
rb_nativethread_lock_lock(&ca_id_names_lock);
|
|
522
|
+
if ( st_lookup(ca_id_names, (st_data_t) id, &found) ) {
|
|
523
|
+
xfree(copy);
|
|
524
|
+
name = (const char *) found;
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
st_insert(ca_id_names, (st_data_t) id, (st_data_t) copy);
|
|
528
|
+
name = copy;
|
|
529
|
+
}
|
|
530
|
+
rb_nativethread_lock_unlock(&ca_id_names_lock);
|
|
531
|
+
return name;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/* The method a delegating method answers for. A method that does its work
|
|
536
|
+
by calling others (median calls partition_index, mode calls sort) runs
|
|
537
|
+
them under ca_answer_as_caller, so an error they raise names the method
|
|
538
|
+
the user called. The outermost one wins. */
|
|
539
|
+
static _Thread_local const char *ca_answering_name = NULL;
|
|
540
|
+
|
|
541
|
+
static VALUE
|
|
542
|
+
ca_answer_restore (VALUE unused)
|
|
543
|
+
{
|
|
544
|
+
ca_answering_name = NULL;
|
|
545
|
+
return Qnil;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
VALUE
|
|
549
|
+
ca_answer_as_caller (VALUE (*body)(VALUE), VALUE arg)
|
|
550
|
+
{
|
|
551
|
+
if ( ca_answering_name ) {
|
|
552
|
+
return body(arg);
|
|
553
|
+
}
|
|
554
|
+
ca_answering_name = ca_calling_method_name();
|
|
555
|
+
return rb_ensure(body, arg, ca_answer_restore, Qnil);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* CArray.__answer_as__(name) { ... }: the same for a method written in Ruby. */
|
|
559
|
+
static VALUE
|
|
560
|
+
rb_ca_s_answer_as_body (VALUE unused)
|
|
561
|
+
{
|
|
562
|
+
return rb_yield(Qnil);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
static VALUE
|
|
566
|
+
rb_ca_s_answer_as (VALUE klass, VALUE name)
|
|
567
|
+
{
|
|
568
|
+
if ( ca_answering_name ) {
|
|
569
|
+
return rb_yield(Qnil);
|
|
570
|
+
}
|
|
571
|
+
ca_answering_name = ca_stable_id_name(rb_to_id(name));
|
|
572
|
+
return rb_ensure(rb_ca_s_answer_as_body, Qnil, ca_answer_restore, Qnil);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const char *
|
|
576
|
+
ca_calling_method_name (void)
|
|
577
|
+
{
|
|
578
|
+
ID id;
|
|
579
|
+
const char *s;
|
|
580
|
+
size_t n;
|
|
581
|
+
if ( ca_answering_name ) {
|
|
582
|
+
return ca_answering_name;
|
|
583
|
+
}
|
|
584
|
+
id = rb_frame_this_func();
|
|
585
|
+
if ( ! id ) {
|
|
586
|
+
return "axis";
|
|
587
|
+
}
|
|
588
|
+
s = ca_stable_id_name(id);
|
|
589
|
+
if ( ! s ) {
|
|
590
|
+
return "axis";
|
|
591
|
+
}
|
|
592
|
+
n = strlen(s);
|
|
593
|
+
if ( n > 3 && strcmp(s + n - 3, "_ki") == 0 ) {
|
|
594
|
+
return ca_stable_id_name(rb_intern2(s, (long) (n - 3)));
|
|
595
|
+
}
|
|
596
|
+
return s;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/* The Integer value of an integer argument (`axis`, `kth`, `min_count`,
|
|
600
|
+
...). Anything else -- a Float included, which NUM2LONG would truncate
|
|
601
|
+
-- is a TypeError. `arg` is the argument's name; `name` names the method
|
|
602
|
+
in the message, NULL for the method the user called. */
|
|
603
|
+
/* The number of cells in a shape. A shape whose cell count, or whose size
|
|
604
|
+
at `bytes` a cell, does not fit ca_size_t is refused: wrapped, the count
|
|
605
|
+
would describe a smaller array than the view addresses, and every read
|
|
606
|
+
and write past it would leave the buffer. Negative extents are the
|
|
607
|
+
caller's to refuse, with its own message. */
|
|
608
|
+
ca_size_t
|
|
609
|
+
ca_shape_elements (int8_t ndim, const ca_size_t *dim, ca_size_t bytes)
|
|
610
|
+
{
|
|
611
|
+
ca_size_t elements = 1, total;
|
|
612
|
+
int8_t i;
|
|
613
|
+
for ( i = 0; i < ndim; i++ ) {
|
|
614
|
+
if ( dim[i] == 0 ) return 0; /* empty, whatever the other extents */
|
|
615
|
+
}
|
|
616
|
+
for ( i = 0; i < ndim; i++ ) {
|
|
617
|
+
if ( __builtin_mul_overflow(elements, dim[i], &elements) ) {
|
|
618
|
+
rb_raise(rb_eArgError, "too large byte length");
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if ( __builtin_mul_overflow(elements, (bytes > 0 ? bytes : 1), &total) ) {
|
|
622
|
+
rb_raise(rb_eArgError, "too large byte length");
|
|
623
|
+
}
|
|
624
|
+
return elements;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/* An index array is read as ca_size_t. A uint64 one holding 2**63 or more
|
|
628
|
+
would turn negative on the way and count from the end of the axis, so it
|
|
629
|
+
is refused here as the out-of-range index it is. */
|
|
630
|
+
void
|
|
631
|
+
ca_check_index_array (VALUE v)
|
|
632
|
+
{
|
|
633
|
+
CArray *ca;
|
|
634
|
+
if ( ! rb_obj_is_carray(v) ) return;
|
|
635
|
+
GetCArray(v, ca);
|
|
636
|
+
if ( ca->data_type != CA_UINT64 || ca->elements == 0 ) return;
|
|
637
|
+
{
|
|
638
|
+
VALUE max = rb_funcall(v, rb_intern("max"), 0);
|
|
639
|
+
if ( rb_obj_is_kind_of(max, rb_cInteger) &&
|
|
640
|
+
RTEST(rb_funcall(max, rb_intern(">"), 1, LL2NUM(CA_LENGTH_MAX))) ) {
|
|
641
|
+
rb_raise(rb_eIndexError, "index %"PRIsVALUE" is out of range", max);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
long
|
|
647
|
+
ca_integer_arg (VALUE v, const char *arg, const char *name)
|
|
648
|
+
{
|
|
649
|
+
if ( ! RB_INTEGER_TYPE_P(v) ) {
|
|
650
|
+
rb_raise(rb_eTypeError, "%s: %s must be an Integer (got %"PRIsVALUE")",
|
|
651
|
+
name ? name : ca_calling_method_name(), arg, rb_obj_class(v));
|
|
652
|
+
}
|
|
653
|
+
return NUM2LONG(v);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
void
|
|
657
|
+
ca_index_out_of_range_at (ca_size_t idx, ca_size_t n, int axis)
|
|
658
|
+
{
|
|
659
|
+
rb_raise(rb_eIndexError,
|
|
660
|
+
"%s: index %lld is out of range for length %lld on axis %d",
|
|
661
|
+
ca_calling_method_name(), (long long) idx, (long long) n, axis);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
void
|
|
665
|
+
ca_obj_compare_refused (VALUE a, VALUE b)
|
|
666
|
+
{
|
|
667
|
+
/* The right-hand value is written as Ruby's own comparison error writes
|
|
668
|
+
it: inspected when it is nil, true, false or a number, its class
|
|
669
|
+
otherwise. */
|
|
670
|
+
volatile VALUE rhs = ( RB_SPECIAL_CONST_P(b) || RB_FLOAT_TYPE_P(b) )
|
|
671
|
+
? rb_inspect(b) : rb_class_name(rb_obj_class(b));
|
|
672
|
+
rb_raise(rb_eArgError, "%s: comparison of %"PRIsVALUE" with %"PRIsVALUE" failed",
|
|
673
|
+
ca_calling_method_name(), rb_class_name(rb_obj_class(a)), rhs);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
void
|
|
677
|
+
ca_index_out_of_range (ca_size_t idx, ca_size_t n, const char *what)
|
|
678
|
+
{
|
|
679
|
+
rb_raise(rb_eIndexError, "%s: %s %lld is out of range for length %lld",
|
|
680
|
+
ca_calling_method_name(), what, (long long) idx, (long long) n);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/* The min_count: keyword of a reduction: nil (not given) is -1, any other
|
|
684
|
+
value an Integer of at least 0. An error names `name`, or the method the
|
|
685
|
+
user called when NULL. See ca_too_few_present. */
|
|
686
|
+
long
|
|
687
|
+
ca_min_count_arg (VALUE v, const char *name)
|
|
688
|
+
{
|
|
689
|
+
long n;
|
|
690
|
+
if ( NIL_P(v) ) {
|
|
691
|
+
return -1;
|
|
692
|
+
}
|
|
693
|
+
n = ca_integer_arg(v, "min_count", name);
|
|
694
|
+
if ( n < 0 ) {
|
|
695
|
+
rb_raise(rb_eArgError, "%s: min_count must be non-negative (got %ld)",
|
|
696
|
+
name ? name : ca_calling_method_name(), n);
|
|
697
|
+
}
|
|
698
|
+
return n;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/* CArray.__min_count_need__(op, min_count, least): how many present cells a
|
|
702
|
+
result cell of `op` needs (ca_too_few_present), for a reduction written
|
|
703
|
+
in Ruby; it masks the cells whose count is below it. */
|
|
704
|
+
static VALUE
|
|
705
|
+
rb_ca_s_min_count_need (VALUE klass, VALUE vop, VALUE vmc, VALUE vleast)
|
|
706
|
+
{
|
|
707
|
+
volatile VALUE name = rb_String(vop);
|
|
708
|
+
long need = NUM2LONG(vleast);
|
|
709
|
+
long mc = ca_min_count_arg(vmc, StringValueCStr(name));
|
|
710
|
+
return LONG2NUM(mc > need ? mc : need);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/* A keyword that names one of two Symbols (`masked_position: :first /
|
|
714
|
+
:last`, `kind: :quick / :stable`, `method: :ordinal / :dense`):
|
|
715
|
+
returns 0 for c0 and 1 for c1. Anything but a Symbol is a TypeError,
|
|
716
|
+
another Symbol an ArgumentError, both naming the method (`name`, or the
|
|
717
|
+
method the user called when NULL). */
|
|
718
|
+
int
|
|
719
|
+
ca_symbol_choice (VALUE v, const char *arg, const char *c0, const char *c1,
|
|
720
|
+
const char *name)
|
|
721
|
+
{
|
|
722
|
+
const char *nm = name ? name : ca_calling_method_name();
|
|
723
|
+
ID id;
|
|
724
|
+
if ( ! SYMBOL_P(v) ) {
|
|
725
|
+
rb_raise(rb_eTypeError, "%s: %s must be a Symbol (got %"PRIsVALUE")",
|
|
726
|
+
nm, arg, rb_obj_class(v));
|
|
727
|
+
}
|
|
728
|
+
id = SYM2ID(v);
|
|
729
|
+
if ( id == rb_intern(c0) ) {
|
|
730
|
+
return 0;
|
|
731
|
+
}
|
|
732
|
+
if ( id == rb_intern(c1) ) {
|
|
733
|
+
return 1;
|
|
734
|
+
}
|
|
735
|
+
rb_raise(rb_eArgError, "%s: unknown %s :%"PRIsVALUE" (expected :%s or :%s)",
|
|
736
|
+
nm, arg, rb_id2str(id), c0, c1);
|
|
737
|
+
return 0;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/* `fill` as a cell of `data_type` holds it: the value a store of `fill`
|
|
741
|
+
into such an array would leave. */
|
|
742
|
+
VALUE
|
|
743
|
+
ca_fill_as (VALUE fill, int8_t data_type)
|
|
744
|
+
{
|
|
745
|
+
ca_size_t dim[1] = { 1 };
|
|
746
|
+
VALUE cell = rb_carray_new(data_type, 1, dim, 0, NULL);
|
|
747
|
+
rb_ca_store_all(cell, fill);
|
|
748
|
+
return rb_ca_fetch_addr(cell, 0);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* The `fill_value:` of a reduction, applied to its result: the masked
|
|
752
|
+
cells of a CArray result are filled as a store would fill them, each
|
|
753
|
+
member of a two-array result (minmax) alike. `whole` says the result
|
|
754
|
+
was computed with every axis kept for a full reduction; its one cell
|
|
755
|
+
is then returned as the scalar the caller asked for. A caller passes
|
|
756
|
+
no fill for `fill_value: UNDEF`, which leaves the cells undefined. */
|
|
757
|
+
VALUE
|
|
758
|
+
ca_reduce_fill (VALUE result, VALUE fill, int whole)
|
|
759
|
+
{
|
|
760
|
+
if ( RB_TYPE_P(result, T_ARRAY) ) {
|
|
761
|
+
long i, n = RARRAY_LEN(result);
|
|
762
|
+
VALUE out = rb_ary_new_capa(n);
|
|
763
|
+
for ( i = 0; i < n; i++ ) {
|
|
764
|
+
rb_ary_push(out, ca_reduce_fill(RARRAY_AREF(result, i), fill, whole));
|
|
765
|
+
}
|
|
766
|
+
return out;
|
|
767
|
+
}
|
|
768
|
+
if ( rb_obj_is_kind_of(result, rb_cCArray) ) {
|
|
769
|
+
CArray *cr;
|
|
770
|
+
GetCArray(result, cr);
|
|
771
|
+
if ( ca_has_mask(cr) ) {
|
|
772
|
+
result = rb_ca_mask_fill_copy(result, fill);
|
|
773
|
+
}
|
|
774
|
+
return whole ? rb_ca_fetch_addr(result, 0) : result;
|
|
775
|
+
}
|
|
776
|
+
return ( result == CA_UNDEF ) ? fill : result;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/* CArray.__reduce_fill__(result, fill_value): ca_reduce_fill for a
|
|
780
|
+
reduction written in Ruby. A fill_value of nil or UNDEF leaves the
|
|
781
|
+
undefined cells as they are. */
|
|
782
|
+
static VALUE
|
|
783
|
+
rb_ca_s_reduce_fill (VALUE klass, VALUE result, VALUE fill)
|
|
784
|
+
{
|
|
785
|
+
if ( NIL_P(fill) || fill == CA_UNDEF ) {
|
|
786
|
+
return result;
|
|
787
|
+
}
|
|
788
|
+
return ca_reduce_fill(result, fill, 0);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/* ca_integer_arg for an `axis` argument. */
|
|
792
|
+
long
|
|
793
|
+
ca_axis_integer (VALUE raxis, const char *name)
|
|
794
|
+
{
|
|
795
|
+
return ca_integer_arg(raxis, "axis", name);
|
|
796
|
+
}
|
|
797
|
+
|
|
485
798
|
/* Self-independent kernel: normalize `raw` against `ndim`, returning a
|
|
486
799
|
canonical non-negative axis in [0, ndim) as int. Accepts negative
|
|
487
800
|
values (Python/Ruby convention: -1 => ndim-1). Raises ArgumentError
|
|
488
801
|
if out of range. `name` is used in the error message (e.g.
|
|
489
|
-
"mask_duplicates", "sum", "merge"); pass NULL to
|
|
802
|
+
"mask_duplicates", "sum", "merge"); pass NULL to use the name of the
|
|
803
|
+
method the user called.
|
|
490
804
|
|
|
491
805
|
For an insertion position (= valid range [0, old_ndim] inclusive),
|
|
492
806
|
pass `old_ndim + 1` as `ndim` so the half-open [0, ndim) check
|
|
@@ -498,7 +812,7 @@ rb_ca_normalize_axis_for_ndim (long raw, int ndim, const char *name)
|
|
|
498
812
|
if ( axis < 0 || axis >= ndim ) {
|
|
499
813
|
rb_raise(rb_eArgError,
|
|
500
814
|
"%s: axis %ld out of range for ndim %d",
|
|
501
|
-
name ? name :
|
|
815
|
+
name ? name : ca_calling_method_name(), raw, ndim);
|
|
502
816
|
}
|
|
503
817
|
return (int) axis;
|
|
504
818
|
}
|
|
@@ -511,7 +825,7 @@ rb_ca_normalize_axis_value (VALUE self, VALUE raxis, const char *name)
|
|
|
511
825
|
{
|
|
512
826
|
CArray *ca;
|
|
513
827
|
GetCArray(self, ca);
|
|
514
|
-
return rb_ca_normalize_axis_for_ndim(
|
|
828
|
+
return rb_ca_normalize_axis_for_ndim(ca_axis_integer(raxis, name), (int) ca->ndim, name);
|
|
515
829
|
}
|
|
516
830
|
|
|
517
831
|
/* Ruby-facing `CArray#normalize_axis(axis, name=nil)` — returns the
|
|
@@ -546,7 +860,7 @@ rb_ca_s_normalize_axis (int argc, VALUE *argv, VALUE klass)
|
|
|
546
860
|
int k;
|
|
547
861
|
rb_scan_args(argc, argv, "21", &raxis, &rndim, &rname);
|
|
548
862
|
name = NIL_P(rname) ? NULL : StringValueCStr(rname);
|
|
549
|
-
k = rb_ca_normalize_axis_for_ndim(
|
|
863
|
+
k = rb_ca_normalize_axis_for_ndim(ca_axis_integer(raxis, name), NUM2INT(rndim), name);
|
|
550
864
|
return INT2NUM(k);
|
|
551
865
|
}
|
|
552
866
|
|
|
@@ -566,7 +880,7 @@ rb_ca_normalize_axes (int argc, VALUE *argv, VALUE self)
|
|
|
566
880
|
const char *name;
|
|
567
881
|
|
|
568
882
|
rb_scan_args(argc, argv, "11", &raxes, &rname);
|
|
569
|
-
name = NIL_P(rname) ?
|
|
883
|
+
name = NIL_P(rname) ? ca_calling_method_name() : StringValueCStr(rname);
|
|
570
884
|
GetCArray(self, ca);
|
|
571
885
|
|
|
572
886
|
if ( NIL_P(raxes) ) {
|
|
@@ -585,67 +899,6 @@ rb_ca_normalize_axes (int argc, VALUE *argv, VALUE self)
|
|
|
585
899
|
return out;
|
|
586
900
|
}
|
|
587
901
|
|
|
588
|
-
/* `CArray._scan_float(str, fill_value=nil)` — parses `str` as a
|
|
589
|
-
* single double via `sscanf("%lf")`. Returns `fill_value` (or NaN
|
|
590
|
-
* when `fill_value` is nil) if `str` is nil or unparseable. Internal
|
|
591
|
-
* helper for text-format I/O readers. */
|
|
592
|
-
|
|
593
|
-
static VALUE
|
|
594
|
-
rb_ca_s_scan_float (int argc, VALUE *argv, VALUE self)
|
|
595
|
-
{
|
|
596
|
-
volatile VALUE rstr, rfval;
|
|
597
|
-
double value;
|
|
598
|
-
int count;
|
|
599
|
-
|
|
600
|
-
rb_scan_args(argc, argv, "11", (VALUE *)&rstr, (VALUE *)&rfval);
|
|
601
|
-
|
|
602
|
-
if ( NIL_P(rstr) ) {
|
|
603
|
-
return ( NIL_P(rfval) ) ? rb_float_new(0.0/0.0) : rfval;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
Check_Type(rstr, T_STRING);
|
|
607
|
-
|
|
608
|
-
count = sscanf(StringValuePtr(rstr), "%lf", &value);
|
|
609
|
-
|
|
610
|
-
if ( count == 1 ) {
|
|
611
|
-
return rb_float_new(value);
|
|
612
|
-
}
|
|
613
|
-
else {
|
|
614
|
-
return ( NIL_P(rfval) ) ? rb_float_new(0.0/0.0) : rfval;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/* `CArray._scan_int(str, fill_value=nil)` — parses `str` as a single
|
|
619
|
-
* integer via `sscanf("%li")` (accepts `0x`, `0`, and decimal
|
|
620
|
-
* prefixes). Returns `fill_value` (or 0 when `fill_value` is nil) if
|
|
621
|
-
* `str` is nil or unparseable. Internal helper for text-format I/O
|
|
622
|
-
* readers. */
|
|
623
|
-
|
|
624
|
-
static VALUE
|
|
625
|
-
rb_ca_s_scan_int (int argc, VALUE *argv, VALUE self)
|
|
626
|
-
{
|
|
627
|
-
volatile VALUE rstr, rfval;
|
|
628
|
-
long value;
|
|
629
|
-
int count;
|
|
630
|
-
|
|
631
|
-
rb_scan_args(argc, argv, "11", (VALUE *) &rstr, (VALUE *) &rfval);
|
|
632
|
-
|
|
633
|
-
if ( NIL_P(rstr) ) {
|
|
634
|
-
return ( NIL_P(rfval) ) ? INT2NUM(0) : rfval;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
Check_Type(rstr, T_STRING);
|
|
638
|
-
|
|
639
|
-
count = sscanf(StringValuePtr(rstr), "%li", &value);
|
|
640
|
-
|
|
641
|
-
if ( count == 1 ) {
|
|
642
|
-
return SIZE2NUM(value);
|
|
643
|
-
}
|
|
644
|
-
else {
|
|
645
|
-
return ( NIL_P(rfval) ) ? INT2NUM(0) : rfval;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
902
|
static const struct {
|
|
650
903
|
const char *name;
|
|
651
904
|
int data_type;
|
|
@@ -685,7 +938,12 @@ rb_ca_guess_type (VALUE obj)
|
|
|
685
938
|
VALUE inspect;
|
|
686
939
|
|
|
687
940
|
if ( TYPE(obj) == T_FIXNUM ) {
|
|
688
|
-
|
|
941
|
+
/* Check before narrowing to int8_t, so the message names the id given. */
|
|
942
|
+
long id = FIX2LONG(obj);
|
|
943
|
+
if ( id <= CA_NONE || id >= CA_NTYPE ) {
|
|
944
|
+
rb_raise(rb_eArgError, "invalid data_type id %ld", id);
|
|
945
|
+
}
|
|
946
|
+
return (int8_t) id;
|
|
689
947
|
}
|
|
690
948
|
else if ( TYPE(obj) == T_STRING ) {
|
|
691
949
|
const char *name0;
|
|
@@ -701,7 +959,7 @@ rb_ca_guess_type (VALUE obj)
|
|
|
701
959
|
}
|
|
702
960
|
}
|
|
703
961
|
else if ( TYPE(obj) == T_SYMBOL ) {
|
|
704
|
-
return rb_ca_guess_type(
|
|
962
|
+
return rb_ca_guess_type(rb_str_dup(rb_sym2str(obj)));
|
|
705
963
|
}
|
|
706
964
|
else if ( TYPE(obj) == T_CLASS ) {
|
|
707
965
|
ca_check_data_class(obj);
|
|
@@ -709,7 +967,7 @@ rb_ca_guess_type (VALUE obj)
|
|
|
709
967
|
}
|
|
710
968
|
|
|
711
969
|
inspect = rb_inspect(obj);
|
|
712
|
-
rb_raise(
|
|
970
|
+
rb_raise(rb_eArgError,
|
|
713
971
|
"<%s> is unknown data_type representation", StringValuePtr(inspect));
|
|
714
972
|
}
|
|
715
973
|
|
|
@@ -754,11 +1012,15 @@ rb_ca_s_guess_type_and_bytes (int argc, VALUE *argv, VALUE klass)
|
|
|
754
1012
|
return rb_assoc_new(INT2NUM(data_type), SIZE2NUM(bytes));
|
|
755
1013
|
}
|
|
756
1014
|
|
|
1015
|
+
/* Takes the trailing keyword Hash off argv when the caller passed keywords.
|
|
1016
|
+
A Hash passed as a positional argument (`f({axis: 0})`) stays an argument,
|
|
1017
|
+
as in Ruby 3: it may be a value, such as a cell of an object array. */
|
|
757
1018
|
VALUE
|
|
758
1019
|
rb_pop_options (int *argc, VALUE **argv)
|
|
759
1020
|
{
|
|
760
1021
|
VALUE ropt;
|
|
761
|
-
if ( ( *argc > 0 ) && (
|
|
1022
|
+
if ( ( *argc > 0 ) && rb_keyword_given_p() &&
|
|
1023
|
+
( TYPE( (*argv)[*argc-1] ) == T_HASH ) ) {
|
|
762
1024
|
ropt = (*argv)[*argc-1];
|
|
763
1025
|
(*argc) -= 1;
|
|
764
1026
|
}
|
|
@@ -928,15 +1190,12 @@ rb_set_options (VALUE ropt, const char *spec_in, ...)
|
|
|
928
1190
|
void
|
|
929
1191
|
Init_carray_utils (void)
|
|
930
1192
|
{
|
|
1193
|
+
ca_id_names = st_init_numtable();
|
|
1194
|
+
rb_nativethread_lock_initialize(&ca_id_names_lock);
|
|
931
1195
|
id_begin = rb_intern("begin");
|
|
932
1196
|
id_end = rb_intern("end");
|
|
933
1197
|
id_excl_end = rb_intern("exclude_end?");
|
|
934
1198
|
|
|
935
|
-
rb_define_singleton_method(rb_cCArray, "_scan_float",
|
|
936
|
-
rb_ca_s_scan_float, -1);
|
|
937
|
-
rb_define_singleton_method(rb_cCArray, "_scan_int",
|
|
938
|
-
rb_ca_s_scan_int, -1);
|
|
939
|
-
|
|
940
1199
|
rb_define_singleton_method(rb_cCArray, "guess_type_and_bytes",
|
|
941
1200
|
rb_ca_s_guess_type_and_bytes, -1);
|
|
942
1201
|
|
|
@@ -944,6 +1203,12 @@ Init_carray_utils (void)
|
|
|
944
1203
|
rb_define_method(rb_cCArray, "normalize_axes", rb_ca_normalize_axes, -1);
|
|
945
1204
|
rb_define_singleton_method(rb_cCArray, "normalize_axis",
|
|
946
1205
|
rb_ca_s_normalize_axis, -1);
|
|
1206
|
+
rb_define_singleton_method(rb_cCArray, "__min_count_need__",
|
|
1207
|
+
rb_ca_s_min_count_need, 3);
|
|
1208
|
+
rb_define_singleton_method(rb_cCArray, "__reduce_fill__",
|
|
1209
|
+
rb_ca_s_reduce_fill, 2);
|
|
1210
|
+
rb_define_singleton_method(rb_cCArray, "__answer_as__",
|
|
1211
|
+
rb_ca_s_answer_as, 1);
|
|
947
1212
|
|
|
948
1213
|
}
|
|
949
1214
|
|