carray 3.0.3 → 3.0.5
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 +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +105 -17
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- data/lib/carray/frame/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +42 -6
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +217 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +61 -37
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_factorize.c
CHANGED
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
(Float#eql? treats them equal). The object lane adds one deviation from Ruby
|
|
51
51
|
Hash, aligning it with the numeric lane: every Float NaN collapses to one
|
|
52
52
|
distinct value (a NaN takes a fixed canonical key and matches any stored Float
|
|
53
|
-
NaN), where Ruby Hash would keep distinct NaN objects apart
|
|
53
|
+
NaN), where Ruby Hash would keep distinct NaN objects apart, and a Complex
|
|
54
|
+
with a NaN part is one value with any Complex whose parts match it that way.
|
|
54
55
|
__factorize_appearance__ and the discovery members (unique, value_counts,
|
|
55
56
|
mask_duplicates) all cover the numeric / object / fixlen lanes.
|
|
56
57
|
|
|
@@ -77,6 +78,7 @@
|
|
|
77
78
|
|
|
78
79
|
#include "carray.h"
|
|
79
80
|
#include "ca_obj_face.h"
|
|
81
|
+
#include "carray_internal.h" /* ca_object_cells_clear */
|
|
80
82
|
#include <string.h>
|
|
81
83
|
#include <math.h>
|
|
82
84
|
|
|
@@ -175,6 +177,7 @@ fz_complex_key (VALUE self)
|
|
|
175
177
|
if ( ca_has_mask(ca) ) {
|
|
176
178
|
ca_copy_mask(co, ca);
|
|
177
179
|
}
|
|
180
|
+
RB_GC_GUARD(self); /* read through ca after rb_carray_new allocates */
|
|
178
181
|
return out;
|
|
179
182
|
}
|
|
180
183
|
|
|
@@ -206,24 +209,19 @@ fz_face_descend (VALUE self, volatile VALUE *pface, const char *name)
|
|
|
206
209
|
}
|
|
207
210
|
if ( ca_is_face(ca) ) {
|
|
208
211
|
/* A record is its bytes: two records are the same value exactly when
|
|
209
|
-
their bytes are, so the fixlen lane answers for it.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
their bytes are, so the fixlen lane answers for it. Any other Face
|
|
213
|
+
is descended only when ORDERABLE. One that cannot be descended must
|
|
214
|
+
not flow on undescended: whatever reads it next reads its storage
|
|
215
|
+
anyway, which is the encoding rather than the values. A Face in this
|
|
216
|
+
position normally never arrives -- CAConstString and CACategorical
|
|
217
|
+
define their own members in Ruby -- but the overrides only fire when
|
|
218
|
+
the Face is the receiver, and this same helper descends the
|
|
219
|
+
*reference* for locate_addr, where it is the argument. */
|
|
220
|
+
if ( ca->obj_type != CA_OBJ_RECORD ) {
|
|
221
|
+
ca_face_require_orderable(self, name, "compare");
|
|
214
222
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
than the values. A Face in this position normally never arrives --
|
|
218
|
-
CAConstString and CACategorical define their own members in Ruby -- but
|
|
219
|
-
the overrides only fire when the Face is the receiver, and this same
|
|
220
|
-
helper descends the *reference* for locate_addr, where it is the
|
|
221
|
-
argument. */
|
|
222
|
-
rb_raise(rb_eArgError,
|
|
223
|
-
"%s: %s is not orderable by storage (a cell encodes the value "
|
|
224
|
-
"rather than being it); convert it first -- %s -- or pass "
|
|
225
|
-
".parent to work in storage space",
|
|
226
|
-
name, rb_obj_classname(self), ca_face_conversion_hint(self));
|
|
223
|
+
*pface = self;
|
|
224
|
+
return rb_ca_strip_face_value(self);
|
|
227
225
|
}
|
|
228
226
|
*pface = Qnil;
|
|
229
227
|
return self;
|
|
@@ -250,6 +248,7 @@ fz_face_reconcile (VALUE reference, VALUE operand, const char *name)
|
|
|
250
248
|
}
|
|
251
249
|
GetCArray(operand, op);
|
|
252
250
|
if ( op->data_type != ca->data_type ) {
|
|
251
|
+
/* coerce: the callers have met both sides at result_type already */
|
|
253
252
|
operand = rb_ca_to_type(operand, INT2NUM(ca->data_type), Qnil);
|
|
254
253
|
}
|
|
255
254
|
return fz_complex_key(operand);
|
|
@@ -402,8 +401,7 @@ fz_hash_alloc (fz_hash *h, ca_size_t cap)
|
|
|
402
401
|
h->cap = cap;
|
|
403
402
|
MEMZERO(h->used, uint8_t, cap);
|
|
404
403
|
if ( has_val ) {
|
|
405
|
-
|
|
406
|
-
for ( i = 0; i < cap; i++ ) h->val[i] = Qnil;
|
|
404
|
+
ca_object_cells_clear(h->val, cap);
|
|
407
405
|
fz_tmp_values(h->hbuf, h->val, cap);
|
|
408
406
|
}
|
|
409
407
|
}
|
|
@@ -512,25 +510,84 @@ fz_is_float_nan (VALUE v)
|
|
|
512
510
|
return RB_FLOAT_TYPE_P(v) && isnan(RFLOAT_VALUE(v));
|
|
513
511
|
}
|
|
514
512
|
|
|
513
|
+
/* True when v holds a NaN that eql? would keep apart from an equal value:
|
|
514
|
+
a Float NaN, or a Complex with a Float NaN part. */
|
|
515
|
+
static int
|
|
516
|
+
fz_obj_has_nan (VALUE v)
|
|
517
|
+
{
|
|
518
|
+
if ( fz_is_float_nan(v) ) {
|
|
519
|
+
return 1;
|
|
520
|
+
}
|
|
521
|
+
return RB_TYPE_P(v, T_COMPLEX)
|
|
522
|
+
&& ( fz_is_float_nan(rb_complex_real(v))
|
|
523
|
+
|| fz_is_float_nan(rb_complex_imag(v)) );
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/* A part of a NaN-bearing value: every NaN is one value, the rest go by
|
|
527
|
+
eql?, as in Ruby Hash. */
|
|
528
|
+
static uint64_t
|
|
529
|
+
fz_obj_part_key (VALUE v)
|
|
530
|
+
{
|
|
531
|
+
return fz_is_float_nan(v) ? FZ_NAN_KEY_DOUBLE : (uint64_t) NUM2LL(rb_hash(v));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
static int
|
|
535
|
+
fz_obj_part_eql (VALUE a, VALUE b)
|
|
536
|
+
{
|
|
537
|
+
if ( fz_is_float_nan(a) || fz_is_float_nan(b) ) {
|
|
538
|
+
return fz_is_float_nan(a) && fz_is_float_nan(b);
|
|
539
|
+
}
|
|
540
|
+
return rb_eql(a, b);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/* The hash key of an object cell. A NaN-bearing value is keyed part by
|
|
544
|
+
part with every NaN as one value, so it matches the numeric lane: all
|
|
545
|
+
NaN are one value, and a complex value is one value when its parts are. */
|
|
546
|
+
static uint64_t
|
|
547
|
+
fz_obj_key (VALUE v, int has_nan)
|
|
548
|
+
{
|
|
549
|
+
if ( ! has_nan ) {
|
|
550
|
+
return (uint64_t) NUM2LL(rb_hash(v));
|
|
551
|
+
}
|
|
552
|
+
if ( RB_TYPE_P(v, T_COMPLEX) ) {
|
|
553
|
+
return fz_obj_part_key(rb_complex_real(v)) * 31u
|
|
554
|
+
^ fz_obj_part_key(rb_complex_imag(v)) ^ 0x9e3779b97f4a7c15ULL;
|
|
555
|
+
}
|
|
556
|
+
return FZ_NAN_KEY_DOUBLE;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/* Whether a stored cell is the same value as v (has_nan from fz_obj_has_nan). */
|
|
560
|
+
static int
|
|
561
|
+
fz_obj_same (VALUE stored, VALUE v, int has_nan)
|
|
562
|
+
{
|
|
563
|
+
if ( ! has_nan ) {
|
|
564
|
+
return rb_eql(stored, v);
|
|
565
|
+
}
|
|
566
|
+
if ( RB_TYPE_P(v, T_COMPLEX) ) {
|
|
567
|
+
return RB_TYPE_P(stored, T_COMPLEX)
|
|
568
|
+
&& fz_obj_part_eql(rb_complex_real(stored), rb_complex_real(v))
|
|
569
|
+
&& fz_obj_part_eql(rb_complex_imag(stored), rb_complex_imag(v));
|
|
570
|
+
}
|
|
571
|
+
return fz_is_float_nan(stored);
|
|
572
|
+
}
|
|
573
|
+
|
|
515
574
|
/* Object-lane intern: key = rb_hash(v) (lossy), collision re-check via rb_eql.
|
|
516
575
|
Matches Ruby Hash distinctness (`hash` + `eql?`) element for element, with one
|
|
517
576
|
value-based exception aligning with the numeric lane: every Float NaN collapses
|
|
518
577
|
to a single distinct value (Ruby Hash keeps distinct NaN objects apart via
|
|
519
|
-
eql?, but the discovery family unifies them)
|
|
520
|
-
|
|
521
|
-
into the first. */
|
|
578
|
+
eql?, but the discovery family unifies them), and so does a Complex whose
|
|
579
|
+
parts are the same with every NaN as one (fz_obj_key / fz_obj_same). */
|
|
522
580
|
static int32_t
|
|
523
581
|
fz_hash_intern_obj (fz_hash *h, VALUE v, int *is_new)
|
|
524
582
|
{
|
|
525
583
|
if ( (h->n + 1) * 10 >= h->cap * 7 ) { fz_hash_grow(h); } /* load factor 0.7 */
|
|
526
|
-
int v_nan =
|
|
527
|
-
uint64_t key = v_nan
|
|
528
|
-
: (uint64_t) NUM2LL(rb_hash(v));
|
|
584
|
+
int v_nan = fz_obj_has_nan(v);
|
|
585
|
+
uint64_t key = fz_obj_key(v, v_nan);
|
|
529
586
|
ca_size_t mask = h->cap - 1;
|
|
530
587
|
ca_size_t slot = FZ_HOME(h, key);
|
|
531
588
|
while ( h->used[slot] ) {
|
|
532
589
|
if ( h->key[slot] == key &&
|
|
533
|
-
(
|
|
590
|
+
fz_obj_same(h->val[slot], v, v_nan) ) {
|
|
534
591
|
*is_new = 0; return h->code[slot];
|
|
535
592
|
}
|
|
536
593
|
slot = (slot + 1) & mask;
|
|
@@ -621,14 +678,13 @@ fz_hash_lookup (fz_hash *h, uint64_t key, int32_t *code_out)
|
|
|
621
678
|
static int
|
|
622
679
|
fz_hash_lookup_obj (fz_hash *h, VALUE v, int32_t *code_out)
|
|
623
680
|
{
|
|
624
|
-
int v_nan =
|
|
625
|
-
uint64_t key = v_nan
|
|
626
|
-
: (uint64_t) NUM2LL(rb_hash(v));
|
|
681
|
+
int v_nan = fz_obj_has_nan(v);
|
|
682
|
+
uint64_t key = fz_obj_key(v, v_nan);
|
|
627
683
|
ca_size_t mask = h->cap - 1;
|
|
628
684
|
ca_size_t slot = FZ_HOME(h, key);
|
|
629
685
|
while ( h->used[slot] ) {
|
|
630
686
|
if ( h->key[slot] == key &&
|
|
631
|
-
(
|
|
687
|
+
fz_obj_same(h->val[slot], v, v_nan) ) {
|
|
632
688
|
if ( code_out ) { *code_out = h->code[slot]; }
|
|
633
689
|
return 1;
|
|
634
690
|
}
|
|
@@ -669,9 +725,7 @@ typedef struct {
|
|
|
669
725
|
static void
|
|
670
726
|
fz_levels_values (fz_levels *l, ca_size_t from)
|
|
671
727
|
{
|
|
672
|
-
|
|
673
|
-
ca_size_t i;
|
|
674
|
-
for ( i = from; i < l->cap; i++ ) v[i] = Qnil;
|
|
728
|
+
ca_object_cells_clear((VALUE *) l->p + from, l->cap - from);
|
|
675
729
|
fz_tmp_values(l->hp, l->p, l->cap);
|
|
676
730
|
}
|
|
677
731
|
|
|
@@ -717,7 +771,13 @@ fz_levels_free (fz_levels *l)
|
|
|
717
771
|
in the middle of a walk. The walks' states live in this frame, outside the
|
|
718
772
|
method's body, and ca_iter_ensure finishes them however the body leaves;
|
|
719
773
|
the tables have owners the unwind collects (fz_tmp_alloc). Slots 0
|
|
720
|
-
and 1 hold a method's own walks, slot 2 the walk of fz_intern_all.
|
|
774
|
+
and 1 hold a method's own walks, slot 2 the walk of fz_intern_all.
|
|
775
|
+
|
|
776
|
+
A body that replaces self or an operand with an array it made (complex
|
|
777
|
+
keys, a Face's storage, an operand brought into self's space) writes the
|
|
778
|
+
new VALUE back into the frame. The walks read it only through its
|
|
779
|
+
CArray *, so a C local alone would leave it to the collector halfway
|
|
780
|
+
through. */
|
|
721
781
|
|
|
722
782
|
typedef struct {
|
|
723
783
|
ca_iter_state st[3];
|
|
@@ -761,7 +821,7 @@ fz_factorize_appearance_body (VALUE arg)
|
|
|
761
821
|
VALUE self = fr->self;
|
|
762
822
|
CArray *ca;
|
|
763
823
|
volatile VALUE face;
|
|
764
|
-
self = fz_face_descend(self, &face, "categorize");
|
|
824
|
+
fr->self = self = fz_face_descend(self, &face, "categorize");
|
|
765
825
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
766
826
|
|
|
767
827
|
int8_t dt = ca->data_type;
|
|
@@ -805,7 +865,7 @@ fz_factorize_appearance_body (VALUE arg)
|
|
|
805
865
|
element to a 64-bit key; equality within one data type is preserved. */
|
|
806
866
|
#define FZ_LOOP(T, WIDEN) \
|
|
807
867
|
do { \
|
|
808
|
-
const T *ip = (const T *) p_in; \
|
|
868
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
809
869
|
uint32_t *op = (uint32_t *) p_out; \
|
|
810
870
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
811
871
|
if ( m && m[i] ) { op[i] = 0xFFFFFFFFu; continue; } \
|
|
@@ -824,7 +884,7 @@ fz_factorize_appearance_body (VALUE arg)
|
|
|
824
884
|
kept as-is), so masked source cells store the sentinel. */
|
|
825
885
|
#define FZ_LOOP_FLOAT(T) \
|
|
826
886
|
do { \
|
|
827
|
-
const T *ip = (const T *) p_in; \
|
|
887
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
828
888
|
uint32_t *op = (uint32_t *) p_out; \
|
|
829
889
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
830
890
|
if ( m && m[i] ) { op[i] = 0xFFFFFFFFu; continue; } \
|
|
@@ -1013,7 +1073,7 @@ fz_mask_duplicates_body (VALUE arg)
|
|
|
1013
1073
|
interns first appearances, so is_new == 0 flags a duplicate. */
|
|
1014
1074
|
#define MD_LOOP(T, WIDEN) \
|
|
1015
1075
|
do { \
|
|
1016
|
-
const T *ip = (const T *) p_in; \
|
|
1076
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1017
1077
|
boolean8_t *op = (boolean8_t *) p_out; \
|
|
1018
1078
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1019
1079
|
if ( m && m[i] ) { op[i] = 0; continue; } \
|
|
@@ -1031,7 +1091,7 @@ fz_mask_duplicates_body (VALUE arg)
|
|
|
1031
1091
|
before the bitwise key. */
|
|
1032
1092
|
#define MD_LOOP_FLOAT(T) \
|
|
1033
1093
|
do { \
|
|
1034
|
-
const T *ip = (const T *) p_in; \
|
|
1094
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1035
1095
|
boolean8_t *op = (boolean8_t *) p_out; \
|
|
1036
1096
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1037
1097
|
if ( m && m[i] ) { op[i] = 0; continue; } \
|
|
@@ -1132,7 +1192,7 @@ fz_unique_flat_body (VALUE arg)
|
|
|
1132
1192
|
VALUE self = fr->self;
|
|
1133
1193
|
CArray *ca;
|
|
1134
1194
|
volatile VALUE face;
|
|
1135
|
-
self = fz_face_descend(self, &face, "unique");
|
|
1195
|
+
fr->self = self = fz_face_descend(self, &face, "unique");
|
|
1136
1196
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1137
1197
|
|
|
1138
1198
|
int8_t dt = ca->data_type;
|
|
@@ -1158,8 +1218,6 @@ fz_unique_flat_body (VALUE arg)
|
|
|
1158
1218
|
else { fz_hash_init(&h); }
|
|
1159
1219
|
fz_levels_init(&lv, (int) ca->bytes, ca->data_type == CA_OBJECT);
|
|
1160
1220
|
|
|
1161
|
-
int8_t axis = (int8_t) (ca->ndim - 1); /* innermost fiber; hash not reset =
|
|
1162
|
-
one seen-set over the whole array */
|
|
1163
1221
|
ca_iter_state *st_in = &fr->st[0];
|
|
1164
1222
|
char *p_in;
|
|
1165
1223
|
boolean8_t *m;
|
|
@@ -1167,7 +1225,7 @@ fz_unique_flat_body (VALUE arg)
|
|
|
1167
1225
|
|
|
1168
1226
|
#define UQ_LOOP(T, WIDEN) \
|
|
1169
1227
|
do { \
|
|
1170
|
-
const T *ip = (const T *) p_in; \
|
|
1228
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1171
1229
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1172
1230
|
if ( m && m[i] ) { continue; } \
|
|
1173
1231
|
uint64_t key = (uint64_t) (WIDEN ip[i]); \
|
|
@@ -1181,7 +1239,7 @@ fz_unique_flat_body (VALUE arg)
|
|
|
1181
1239
|
pushed level is the raw first-seen element. */
|
|
1182
1240
|
#define UQ_LOOP_FLOAT(T) \
|
|
1183
1241
|
do { \
|
|
1184
|
-
const T *ip = (const T *) p_in; \
|
|
1242
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1185
1243
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1186
1244
|
if ( m && m[i] ) { continue; } \
|
|
1187
1245
|
T v = ip[i]; \
|
|
@@ -1220,7 +1278,7 @@ fz_unique_flat_body (VALUE arg)
|
|
|
1220
1278
|
} \
|
|
1221
1279
|
} while (0)
|
|
1222
1280
|
|
|
1223
|
-
|
|
1281
|
+
CA_FOR_EACH_WHOLE_MASKED(*st_in, ca, CA_KERNEL_READ, p_in, n, m) {
|
|
1224
1282
|
switch ( dt ) {
|
|
1225
1283
|
case CA_INT8: UQ_LOOP(int8_t, (int64_t)); break;
|
|
1226
1284
|
case CA_INT16: UQ_LOOP(int16_t, (int64_t)); break;
|
|
@@ -1265,7 +1323,7 @@ rb_ca_unique_flat (VALUE self)
|
|
|
1265
1323
|
}
|
|
1266
1324
|
|
|
1267
1325
|
/* Intern every non-masked cell of cv into h, one seen-set over the whole array
|
|
1268
|
-
|
|
1326
|
+
walked in row-major order. When lv is non-NULL, the first-seen
|
|
1269
1327
|
raw element of each distinct value is pushed to it (appearance order), so the
|
|
1270
1328
|
same pass builds both a probe set and the distinct-value list. Dispatches the
|
|
1271
1329
|
three key lanes exactly as the discovery family: numeric widen with all NaN
|
|
@@ -1276,14 +1334,13 @@ static void
|
|
|
1276
1334
|
fz_intern_all (ca_iter_state *st_v, fz_hash *h, CArray *cv, fz_levels *lv)
|
|
1277
1335
|
{
|
|
1278
1336
|
int8_t dt = cv->data_type;
|
|
1279
|
-
int8_t vaxis = (int8_t) (cv->ndim - 1);
|
|
1280
1337
|
char *p_v;
|
|
1281
1338
|
boolean8_t *mv;
|
|
1282
1339
|
ca_size_t nv;
|
|
1283
1340
|
|
|
1284
1341
|
#define FZ_IA(T, WIDEN) \
|
|
1285
1342
|
do { \
|
|
1286
|
-
const T *ip = (const T *) p_v; \
|
|
1343
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_v; \
|
|
1287
1344
|
for ( ca_size_t i = 0; i < nv; i++ ) { \
|
|
1288
1345
|
if ( mv && mv[i] ) { continue; } \
|
|
1289
1346
|
uint64_t key = (uint64_t) (WIDEN ip[i]); \
|
|
@@ -1295,7 +1352,7 @@ fz_intern_all (ca_iter_state *st_v, fz_hash *h, CArray *cv, fz_levels *lv)
|
|
|
1295
1352
|
|
|
1296
1353
|
#define FZ_IA_FLOAT(T) \
|
|
1297
1354
|
do { \
|
|
1298
|
-
const T *ip = (const T *) p_v; \
|
|
1355
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_v; \
|
|
1299
1356
|
for ( ca_size_t i = 0; i < nv; i++ ) { \
|
|
1300
1357
|
if ( mv && mv[i] ) { continue; } \
|
|
1301
1358
|
T v = ip[i]; \
|
|
@@ -1329,7 +1386,7 @@ fz_intern_all (ca_iter_state *st_v, fz_hash *h, CArray *cv, fz_levels *lv)
|
|
|
1329
1386
|
} \
|
|
1330
1387
|
} while (0)
|
|
1331
1388
|
|
|
1332
|
-
|
|
1389
|
+
CA_FOR_EACH_WHOLE_MASKED(*st_v, cv, CA_KERNEL_READ, p_v, nv, mv) {
|
|
1333
1390
|
switch ( dt ) {
|
|
1334
1391
|
case CA_INT8: FZ_IA(int8_t, (int64_t)); break;
|
|
1335
1392
|
case CA_INT16: FZ_IA(int16_t, (int64_t)); break;
|
|
@@ -1376,8 +1433,8 @@ fz_is_in_body (VALUE arg)
|
|
|
1376
1433
|
VALUE rvalues = fr->a;
|
|
1377
1434
|
CArray *ca, *cv;
|
|
1378
1435
|
volatile VALUE face;
|
|
1379
|
-
self
|
|
1380
|
-
rvalues
|
|
1436
|
+
fr->self = self = fz_face_descend(self, &face, "is_in");
|
|
1437
|
+
fr->a = rvalues = fz_face_reconcile(face, rvalues, "is_in");
|
|
1381
1438
|
GetCArray(self, ca);
|
|
1382
1439
|
|
|
1383
1440
|
int8_t dt = ca->data_type;
|
|
@@ -1436,7 +1493,7 @@ fz_is_in_body (VALUE arg)
|
|
|
1436
1493
|
|
|
1437
1494
|
#define IN_PROBE(T, WIDEN) \
|
|
1438
1495
|
do { \
|
|
1439
|
-
const T *ip = (const T *) p_in; \
|
|
1496
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1440
1497
|
boolean8_t *op = (boolean8_t *) p_out; \
|
|
1441
1498
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1442
1499
|
if ( m && m[i] ) { op[i] = 0; continue; } \
|
|
@@ -1447,7 +1504,7 @@ fz_is_in_body (VALUE arg)
|
|
|
1447
1504
|
|
|
1448
1505
|
#define IN_PROBE_FLOAT(T) \
|
|
1449
1506
|
do { \
|
|
1450
|
-
const T *ip = (const T *) p_in; \
|
|
1507
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1451
1508
|
boolean8_t *op = (boolean8_t *) p_out; \
|
|
1452
1509
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1453
1510
|
if ( m && m[i] ) { op[i] = 0; continue; } \
|
|
@@ -1543,8 +1600,8 @@ fz_locate_addr_body (VALUE arg)
|
|
|
1543
1600
|
output is an address, so nothing is lifted back. */
|
|
1544
1601
|
{
|
|
1545
1602
|
volatile VALUE ref_face;
|
|
1546
|
-
rref = fz_face_descend(rref, &ref_face, "locate_addr");
|
|
1547
|
-
self = fz_face_reconcile(ref_face, self, "locate_addr");
|
|
1603
|
+
fr->a = rref = fz_face_descend(rref, &ref_face, "locate_addr");
|
|
1604
|
+
fr->self = self = fz_face_reconcile(ref_face, self, "locate_addr");
|
|
1548
1605
|
}
|
|
1549
1606
|
GetCArray(self, ca);
|
|
1550
1607
|
|
|
@@ -1604,7 +1661,7 @@ fz_locate_addr_body (VALUE arg)
|
|
|
1604
1661
|
|
|
1605
1662
|
#define LOC_BUILD(T, WIDEN) \
|
|
1606
1663
|
do { \
|
|
1607
|
-
const T *ip = (const T *) p_r; \
|
|
1664
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_r; \
|
|
1608
1665
|
for ( ca_size_t i = 0; i < nr; i++ ) { \
|
|
1609
1666
|
if ( mr && mr[i] ) { continue; } \
|
|
1610
1667
|
uint64_t key = (uint64_t) (WIDEN ip[i]); \
|
|
@@ -1617,7 +1674,7 @@ fz_locate_addr_body (VALUE arg)
|
|
|
1617
1674
|
|
|
1618
1675
|
#define LOC_BUILD_FLOAT(T) \
|
|
1619
1676
|
do { \
|
|
1620
|
-
const T *ip = (const T *) p_r; \
|
|
1677
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_r; \
|
|
1621
1678
|
for ( ca_size_t i = 0; i < nr; i++ ) { \
|
|
1622
1679
|
if ( mr && mr[i] ) { continue; } \
|
|
1623
1680
|
T v = ip[i]; \
|
|
@@ -1694,7 +1751,7 @@ fz_locate_addr_body (VALUE arg)
|
|
|
1694
1751
|
|
|
1695
1752
|
#define LOC_PROBE(T, WIDEN) \
|
|
1696
1753
|
do { \
|
|
1697
|
-
const T *ip = (const T *) p_in; \
|
|
1754
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1698
1755
|
const int64_t *ab = (const int64_t *) addr.p; \
|
|
1699
1756
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1700
1757
|
ca_size_t o = base + i; \
|
|
@@ -1708,7 +1765,7 @@ fz_locate_addr_body (VALUE arg)
|
|
|
1708
1765
|
|
|
1709
1766
|
#define LOC_PROBE_FLOAT(T) \
|
|
1710
1767
|
do { \
|
|
1711
|
-
const T *ip = (const T *) p_in; \
|
|
1768
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
1712
1769
|
const int64_t *ab = (const int64_t *) addr.p; \
|
|
1713
1770
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1714
1771
|
ca_size_t o = base + i; \
|
|
@@ -1807,8 +1864,8 @@ fz_set_relation_body (VALUE arg)
|
|
|
1807
1864
|
int keep_when_hit = fr->i;
|
|
1808
1865
|
CArray *ca, *co;
|
|
1809
1866
|
volatile VALUE face;
|
|
1810
|
-
self = fz_face_descend(self, &face, "set relation");
|
|
1811
|
-
rother = fz_face_reconcile(face, rother, "set relation");
|
|
1867
|
+
fr->self = self = fz_face_descend(self, &face, "set relation");
|
|
1868
|
+
fr->a = rother = fz_face_reconcile(face, rother, "set relation");
|
|
1812
1869
|
GetCArray(self, ca);
|
|
1813
1870
|
|
|
1814
1871
|
int8_t dt = ca->data_type;
|
|
@@ -1872,7 +1929,7 @@ fz_set_relation_body (VALUE arg)
|
|
|
1872
1929
|
|
|
1873
1930
|
#define SR(T, WIDEN) \
|
|
1874
1931
|
do { \
|
|
1875
|
-
const T *ip = (const T *) p; \
|
|
1932
|
+
const CA_U(T) *ip = (const CA_U(T) *) p; \
|
|
1876
1933
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1877
1934
|
if ( m && m[i] ) { continue; } \
|
|
1878
1935
|
uint64_t key = (uint64_t) (WIDEN ip[i]); \
|
|
@@ -1886,7 +1943,7 @@ fz_set_relation_body (VALUE arg)
|
|
|
1886
1943
|
|
|
1887
1944
|
#define SR_FLOAT(T) \
|
|
1888
1945
|
do { \
|
|
1889
|
-
const T *ip = (const T *) p; \
|
|
1946
|
+
const CA_U(T) *ip = (const CA_U(T) *) p; \
|
|
1890
1947
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
1891
1948
|
if ( m && m[i] ) { continue; } \
|
|
1892
1949
|
T v = ip[i]; \
|
|
@@ -2002,8 +2059,8 @@ fz_set_union_body (VALUE arg)
|
|
|
2002
2059
|
VALUE rother = fr->a;
|
|
2003
2060
|
CArray *ca, *co;
|
|
2004
2061
|
volatile VALUE face;
|
|
2005
|
-
self = fz_face_descend(self, &face, "union");
|
|
2006
|
-
rother = fz_face_reconcile(face, rother, "union");
|
|
2062
|
+
fr->self = self = fz_face_descend(self, &face, "union");
|
|
2063
|
+
fr->a = rother = fz_face_reconcile(face, rother, "union");
|
|
2007
2064
|
GetCArray(self, ca);
|
|
2008
2065
|
|
|
2009
2066
|
int8_t dt = ca->data_type;
|
|
@@ -2095,7 +2152,7 @@ fz_value_counts_flat_body (VALUE arg)
|
|
|
2095
2152
|
VALUE self = fr->self;
|
|
2096
2153
|
CArray *ca;
|
|
2097
2154
|
volatile VALUE face;
|
|
2098
|
-
self = fz_face_descend(self, &face, "value_counts");
|
|
2155
|
+
fr->self = self = fz_face_descend(self, &face, "value_counts");
|
|
2099
2156
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
2100
2157
|
|
|
2101
2158
|
int8_t dt = ca->data_type;
|
|
@@ -2131,7 +2188,7 @@ fz_value_counts_flat_body (VALUE arg)
|
|
|
2131
2188
|
|
|
2132
2189
|
#define VC_LOOP(T, WIDEN) \
|
|
2133
2190
|
do { \
|
|
2134
|
-
const T *ip = (const T *) p_in; \
|
|
2191
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
2135
2192
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
2136
2193
|
if ( m && m[i] ) { continue; } \
|
|
2137
2194
|
uint64_t key = (uint64_t) (WIDEN ip[i]); \
|
|
@@ -2149,7 +2206,7 @@ fz_value_counts_flat_body (VALUE arg)
|
|
|
2149
2206
|
|
|
2150
2207
|
#define VC_LOOP_FLOAT(T) \
|
|
2151
2208
|
do { \
|
|
2152
|
-
const T *ip = (const T *) p_in; \
|
|
2209
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
2153
2210
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
2154
2211
|
if ( m && m[i] ) { continue; } \
|
|
2155
2212
|
T v = ip[i]; \
|
|
@@ -2255,10 +2312,10 @@ rb_ca_value_counts_flat (VALUE self)
|
|
|
2255
2312
|
|
|
2256
2313
|
/* @overload __nunique__(axis, keep_axis)
|
|
2257
2314
|
|
|
2258
|
-
INTERNAL (CArray#nunique). Count the distinct values along axis
|
|
2259
|
-
pass per fiber with an independent
|
|
2260
|
-
CA_INT64 CArray of self.shape with
|
|
2261
|
-
keep_axis). Masked cells do not participate; an all-masked fiber counts 0
|
|
2315
|
+
INTERNAL (CArray#nunique). Count the distinct values along axis (an Integer
|
|
2316
|
+
or an Array of them), one linear pass per fiber with an independent
|
|
2317
|
+
seen-set. Returns a reduced CA_INT64 CArray of self.shape with the axes
|
|
2318
|
+
removed (or kept as length-1 when keep_axis). Masked cells do not participate; an all-masked fiber counts 0
|
|
2262
2319
|
(an empty set has zero distinct values, not UNDEF -- nunique has identity 0).
|
|
2263
2320
|
Numeric distinctness collapses all NaN to one value and treats -0.0 == +0.0;
|
|
2264
2321
|
object keys on rb_hash + rb_eql and fixlen on a byte-hash + memcmp, reproducing
|
|
@@ -2290,14 +2347,11 @@ fz_nunique_body (VALUE arg)
|
|
|
2290
2347
|
rb_raise(rb_eRuntimeError, "__nunique__: need ndim >= 1");
|
|
2291
2348
|
}
|
|
2292
2349
|
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
rb_raise(rb_eArgError, "__nunique__: axis %d out of range", axis);
|
|
2296
|
-
}
|
|
2350
|
+
int8_t axes[CA_RANK_MAX];
|
|
2351
|
+
int8_t naxes = rb_ca_parse_reduce_axes_kw_ctx(vaxis, ca, axes, "nunique");
|
|
2297
2352
|
int keep_axis = RTEST(vkeep);
|
|
2298
2353
|
|
|
2299
|
-
|
|
2300
|
-
VALUE vout = rb_ca_new_reduced(self, &ax, 1, CA_INT64, keep_axis);
|
|
2354
|
+
VALUE vout = rb_ca_new_reduced(self, axes, naxes, CA_INT64, keep_axis);
|
|
2301
2355
|
CArray *cout;
|
|
2302
2356
|
TypedData_Get_Struct(vout, CArray, &carray_data_type, cout);
|
|
2303
2357
|
int64_t *op = (int64_t *) cout->ptr;
|
|
@@ -2308,7 +2362,7 @@ fz_nunique_body (VALUE arg)
|
|
|
2308
2362
|
else { fz_hash_init(&h); }
|
|
2309
2363
|
|
|
2310
2364
|
ca_iter_state *st = &fr->st[0];
|
|
2311
|
-
int rc = ca_iter_state_init_l2(st, ca, CA_SLAB_AXES,
|
|
2365
|
+
int rc = ca_iter_state_init_l2(st, ca, CA_SLAB_AXES, axes, naxes, 0);
|
|
2312
2366
|
if ( rc != CA_ITER_OK ) {
|
|
2313
2367
|
fz_hash_free(&h);
|
|
2314
2368
|
rb_raise(rb_eRuntimeError, "__nunique__: kernel_iterator init failed rc=%d", rc);
|
|
@@ -2462,7 +2516,7 @@ fz_is_mode_body (VALUE arg)
|
|
|
2462
2516
|
/* Integer: WIDEN gives the key directly. Two passes over the fiber. */
|
|
2463
2517
|
#define IM_BODY(T, WIDEN) \
|
|
2464
2518
|
do { \
|
|
2465
|
-
const T *ip = (const T *) p_in; \
|
|
2519
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
2466
2520
|
boolean8_t *op = (boolean8_t *) p_out; \
|
|
2467
2521
|
for ( ca_size_t i = 0; i < n; i++ ) { \
|
|
2468
2522
|
if ( m && m[i] ) { continue; } \
|
|
@@ -2489,7 +2543,7 @@ fz_is_mode_body (VALUE arg)
|
|
|
2489
2543
|
/* Float: NaN collapses to one canonical key; -0.0 / +0.0 share a key. */
|
|
2490
2544
|
#define IM_BODY_FLOAT(T) \
|
|
2491
2545
|
do { \
|
|
2492
|
-
const T *ip = (const T *) p_in; \
|
|
2546
|
+
const CA_U(T) *ip = (const CA_U(T) *) p_in; \
|
|
2493
2547
|
boolean8_t *op = (boolean8_t *) p_out; \
|
|
2494
2548
|
for ( int pass = 0; pass < 2; pass++ ) { \
|
|
2495
2549
|
int64_t mx = 0; \
|
|
@@ -2641,7 +2695,7 @@ fz_mode_axis_body (VALUE arg)
|
|
|
2641
2695
|
VALUE vaxis = fr->a;
|
|
2642
2696
|
CArray *ca;
|
|
2643
2697
|
volatile VALUE face;
|
|
2644
|
-
self = fz_face_descend(self, &face, "mode");
|
|
2698
|
+
fr->self = self = fz_face_descend(self, &face, "mode");
|
|
2645
2699
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
2646
2700
|
|
|
2647
2701
|
int8_t dt = ca->data_type;
|