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_mask.c
CHANGED
|
@@ -37,16 +37,32 @@
|
|
|
37
37
|
#define CA_MASK_WORD_BYTES 8
|
|
38
38
|
#define CA_MASK_WORD_LSB 0x0101010101010101ULL
|
|
39
39
|
|
|
40
|
+
/* A mask may start at any byte (a window or a block view offsets it), so a
|
|
41
|
+
word is read and written through memcpy, never through a uint64_t
|
|
42
|
+
pointer; the compiler still lowers each to a single load or store. */
|
|
43
|
+
static inline uint64_t
|
|
44
|
+
ca_mask_word_load (const boolean8_t *p)
|
|
45
|
+
{
|
|
46
|
+
uint64_t w;
|
|
47
|
+
memcpy(&w, p, sizeof(w));
|
|
48
|
+
return w;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static inline void
|
|
52
|
+
ca_mask_word_store (boolean8_t *p, uint64_t w)
|
|
53
|
+
{
|
|
54
|
+
memcpy(p, &w, sizeof(w));
|
|
55
|
+
}
|
|
56
|
+
|
|
40
57
|
/* ma[i] |= ms[i] for i in [0, n) -- used by ca_copy_mask_overlay_n */
|
|
41
58
|
static inline void
|
|
42
59
|
ca_mask_word_or (boolean8_t *ma, const boolean8_t *ms, ca_size_t n)
|
|
43
60
|
{
|
|
44
61
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
45
62
|
ca_size_t i;
|
|
46
|
-
uint64_t *wa = (uint64_t *) ma;
|
|
47
|
-
const uint64_t *ws = (const uint64_t *) ms;
|
|
48
63
|
for (i = 0; i < nw; i++) {
|
|
49
|
-
|
|
64
|
+
ca_mask_word_store(ma + i*CA_MASK_WORD_BYTES,
|
|
65
|
+
ca_mask_word_load(ma + i*CA_MASK_WORD_BYTES) | ca_mask_word_load(ms + i*CA_MASK_WORD_BYTES));
|
|
50
66
|
}
|
|
51
67
|
for (i = nw * CA_MASK_WORD_BYTES; i < n; i++) {
|
|
52
68
|
ma[i] |= ms[i];
|
|
@@ -62,11 +78,9 @@ ca_mask_word_and (boolean8_t *md,
|
|
|
62
78
|
{
|
|
63
79
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
64
80
|
ca_size_t i;
|
|
65
|
-
uint64_t *wd = (uint64_t *) md;
|
|
66
|
-
const uint64_t *wa = (const uint64_t *) ma;
|
|
67
|
-
const uint64_t *wb = (const uint64_t *) mb;
|
|
68
81
|
for (i = 0; i < nw; i++) {
|
|
69
|
-
|
|
82
|
+
ca_mask_word_store(md + i*CA_MASK_WORD_BYTES,
|
|
83
|
+
ca_mask_word_load(ma + i*CA_MASK_WORD_BYTES) & ca_mask_word_load(mb + i*CA_MASK_WORD_BYTES));
|
|
70
84
|
}
|
|
71
85
|
for (i = nw * CA_MASK_WORD_BYTES; i < n; i++) {
|
|
72
86
|
md[i] = ma[i] & mb[i];
|
|
@@ -82,11 +96,9 @@ ca_mask_word_xor (boolean8_t *md,
|
|
|
82
96
|
{
|
|
83
97
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
84
98
|
ca_size_t i;
|
|
85
|
-
uint64_t *wd = (uint64_t *) md;
|
|
86
|
-
const uint64_t *wa = (const uint64_t *) ma;
|
|
87
|
-
const uint64_t *wb = (const uint64_t *) mb;
|
|
88
99
|
for (i = 0; i < nw; i++) {
|
|
89
|
-
|
|
100
|
+
ca_mask_word_store(md + i*CA_MASK_WORD_BYTES,
|
|
101
|
+
ca_mask_word_load(ma + i*CA_MASK_WORD_BYTES) ^ ca_mask_word_load(mb + i*CA_MASK_WORD_BYTES));
|
|
90
102
|
}
|
|
91
103
|
for (i = nw * CA_MASK_WORD_BYTES; i < n; i++) {
|
|
92
104
|
md[i] = ma[i] ^ mb[i];
|
|
@@ -99,10 +111,8 @@ ca_mask_word_not (boolean8_t *md, const boolean8_t *ms, ca_size_t n)
|
|
|
99
111
|
{
|
|
100
112
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
101
113
|
ca_size_t i;
|
|
102
|
-
uint64_t *wd = (uint64_t *) md;
|
|
103
|
-
const uint64_t *ws = (const uint64_t *) ms;
|
|
104
114
|
for (i = 0; i < nw; i++) {
|
|
105
|
-
|
|
115
|
+
ca_mask_word_store(md + i*CA_MASK_WORD_BYTES, ca_mask_word_load(ms + i*CA_MASK_WORD_BYTES) ^ CA_MASK_WORD_LSB);
|
|
106
116
|
}
|
|
107
117
|
for (i = nw * CA_MASK_WORD_BYTES; i < n; i++) {
|
|
108
118
|
md[i] = ms[i] ^ (boolean8_t) 1;
|
|
@@ -116,9 +126,8 @@ ca_mask_word_any (const boolean8_t *m, ca_size_t n)
|
|
|
116
126
|
{
|
|
117
127
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
118
128
|
ca_size_t i;
|
|
119
|
-
const uint64_t *w = (const uint64_t *) m;
|
|
120
129
|
for (i = 0; i < nw; i++) {
|
|
121
|
-
if (
|
|
130
|
+
if ( ca_mask_word_load(m + i*CA_MASK_WORD_BYTES) != 0 ) return 1;
|
|
122
131
|
}
|
|
123
132
|
for (i = nw * CA_MASK_WORD_BYTES; i < n; i++) {
|
|
124
133
|
if ( m[i] ) return 1;
|
|
@@ -134,9 +143,8 @@ ca_mask_word_all_set (const boolean8_t *m, ca_size_t n)
|
|
|
134
143
|
{
|
|
135
144
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
136
145
|
ca_size_t i;
|
|
137
|
-
const uint64_t *w = (const uint64_t *) m;
|
|
138
146
|
for (i = 0; i < nw; i++) {
|
|
139
|
-
if (
|
|
147
|
+
if ( ca_mask_word_load(m + i*CA_MASK_WORD_BYTES) != CA_MASK_WORD_LSB ) return 0;
|
|
140
148
|
}
|
|
141
149
|
for (i = nw * CA_MASK_WORD_BYTES; i < n; i++) {
|
|
142
150
|
if ( ! m[i] ) return 0;
|
|
@@ -423,85 +431,221 @@ ca_create_mask_attach (VALUE arg)
|
|
|
423
431
|
}
|
|
424
432
|
|
|
425
433
|
CArray *
|
|
426
|
-
|
|
434
|
+
ca_mask_standin_new (CArray *parent)
|
|
427
435
|
{
|
|
428
|
-
*
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if ( ca_is_readonly(p) ) {
|
|
433
|
-
ca_set_flag(z, CA_FLAG_READ_ONLY);
|
|
434
|
-
}
|
|
435
|
-
*standin = z;
|
|
436
|
-
return z;
|
|
436
|
+
CArray *z = carray_new(CA_BOOLEAN, parent->ndim, parent->dim, 0, NULL);
|
|
437
|
+
MEMZERO(z->ptr, boolean8_t, z->elements);
|
|
438
|
+
if ( ca_is_readonly(parent) ) {
|
|
439
|
+
ca_set_flag(z, CA_FLAG_READ_ONLY);
|
|
437
440
|
}
|
|
438
|
-
|
|
439
|
-
return p->mask;
|
|
441
|
+
return z;
|
|
440
442
|
}
|
|
441
443
|
|
|
442
444
|
/* A value array or a mask array: a parent that can never be given a mask,
|
|
443
445
|
whose stand-in therefore stays in place for good. */
|
|
444
446
|
static int
|
|
445
|
-
|
|
447
|
+
ca_mask_standin_parent_unmaskable (CArray *parent)
|
|
448
|
+
{
|
|
449
|
+
return ca_is_value_array(parent) || ca_is_mask_array(parent);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
CArray *
|
|
453
|
+
ca_mask_standin_current (CArray *mask_view, CArray *reading, CArray *parent,
|
|
454
|
+
CArray *standin)
|
|
455
|
+
{
|
|
456
|
+
if ( standin == NULL || reading != standin
|
|
457
|
+
|| ca_mask_standin_parent_unmaskable(parent) ) {
|
|
458
|
+
return reading;
|
|
459
|
+
}
|
|
460
|
+
/* Not inside an attach window whose buffer is out: that buffer and the
|
|
461
|
+
detach to come are those of the stand-in. The attach and allocate
|
|
462
|
+
slots run before the buffer is published, and may still give way. */
|
|
463
|
+
if ( CAVIEW(mask_view)->attach > 0 && mask_view->ptr != NULL ) {
|
|
464
|
+
return reading;
|
|
465
|
+
}
|
|
466
|
+
/* A read-only parent (a lazy expression, a broadcast) is never given a
|
|
467
|
+
mask by a write, but can still have one later through its operand or
|
|
468
|
+
root. */
|
|
469
|
+
if ( ! ca_has_mask(parent) ) {
|
|
470
|
+
return reading;
|
|
471
|
+
}
|
|
472
|
+
ca_create_mask(parent);
|
|
473
|
+
return ( parent->mask != NULL ) ? parent->mask : reading;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
void
|
|
477
|
+
ca_mask_standin_settle (CArray *parent, CArray *standin)
|
|
478
|
+
{
|
|
479
|
+
volatile VALUE holder = 0;
|
|
480
|
+
boolean8_t *z, one = 1;
|
|
481
|
+
ca_size_t *addrs;
|
|
482
|
+
ca_size_t i, m = 0, n;
|
|
483
|
+
|
|
484
|
+
if ( standin == NULL || ca_test_flag(standin, CA_FLAG_READ_ONLY) ) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
z = (boolean8_t *) standin->ptr;
|
|
488
|
+
n = standin->elements;
|
|
489
|
+
for ( i = 0; i < n && ! z[i]; i++ ) ;
|
|
490
|
+
if ( i == n ) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if ( ca_mask_standin_parent_unmaskable(parent) ) {
|
|
494
|
+
MEMZERO(z, boolean8_t, n);
|
|
495
|
+
rb_raise(rb_eTypeError, "can not create mask array for the %s array",
|
|
496
|
+
ca_is_value_array(parent) ? "value" : "mask");
|
|
497
|
+
}
|
|
498
|
+
ca_create_mask(parent);
|
|
499
|
+
/* The trues are added to the parent's mask, not copied over it: the
|
|
500
|
+
parent may have come to have masked cells of its own meanwhile. */
|
|
501
|
+
addrs = ALLOCV_N(ca_size_t, holder, n);
|
|
502
|
+
for ( ; i < n; i++ ) {
|
|
503
|
+
if ( z[i] ) {
|
|
504
|
+
addrs[m++] = i;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
ca_fill_addrs(parent->mask, m, addrs, &one);
|
|
508
|
+
ALLOCV_END(holder);
|
|
509
|
+
MEMZERO(z, boolean8_t, n);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
CArray *
|
|
513
|
+
ca_multi_parent_mask (CArray *p, CArray **standin)
|
|
446
514
|
{
|
|
447
|
-
|
|
515
|
+
*standin = NULL;
|
|
516
|
+
if ( ! ca_has_mask(p) ) {
|
|
517
|
+
*standin = ca_mask_standin_new(p);
|
|
518
|
+
return *standin;
|
|
519
|
+
}
|
|
520
|
+
ca_create_mask(p);
|
|
521
|
+
return p->mask;
|
|
448
522
|
}
|
|
449
523
|
|
|
450
524
|
void
|
|
451
525
|
ca_multi_parent_mask_refresh (CArray *mask, CArray **parents,
|
|
452
|
-
CArray **standins, int32_t n
|
|
526
|
+
CArray **standins, int32_t n)
|
|
453
527
|
{
|
|
454
528
|
CAMultiParent *mp = (CAMultiParent *) mask;
|
|
455
529
|
int32_t k;
|
|
456
|
-
|
|
457
|
-
the parents it was opened with. The attach and allocate slots run
|
|
458
|
-
before the buffer is published, and replace the stand-ins then. */
|
|
459
|
-
if ( standins == NULL || ( CAVIEW(mask)->attach > 0 && mask->ptr != NULL ) ) {
|
|
530
|
+
if ( standins == NULL ) {
|
|
460
531
|
return;
|
|
461
532
|
}
|
|
462
533
|
/* A replaced stand-in stays allocated until the view is freed: a copy
|
|
463
534
|
of the mask (dup) may still point at it. */
|
|
464
535
|
for ( k = 0; k < n; k++ ) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
536
|
+
mp->parents[k] = ca_mask_standin_current(mask, mp->parents[k], parents[k],
|
|
537
|
+
standins[k]);
|
|
538
|
+
}
|
|
539
|
+
CAVIEW(mask)->parent = mp->parents[0];
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
typedef struct {
|
|
543
|
+
CArray *mask;
|
|
544
|
+
CArray **blanks;
|
|
545
|
+
CArray **saved;
|
|
546
|
+
CArray *saved_parent;
|
|
547
|
+
int32_t n;
|
|
548
|
+
int finished;
|
|
549
|
+
VALUE (*body)(VALUE);
|
|
550
|
+
VALUE arg;
|
|
551
|
+
} ca_mp_trial_t;
|
|
552
|
+
|
|
553
|
+
static VALUE
|
|
554
|
+
ca_mp_trial_body (VALUE p)
|
|
555
|
+
{
|
|
556
|
+
ca_mp_trial_t *t = (ca_mp_trial_t *) p;
|
|
557
|
+
t->body(t->arg);
|
|
558
|
+
t->finished = 1;
|
|
559
|
+
return Qnil;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
static void
|
|
563
|
+
ca_mp_trial_free_blanks (ca_mp_trial_t *t)
|
|
564
|
+
{
|
|
565
|
+
int32_t k;
|
|
566
|
+
for ( k = 0; k < t->n; k++ ) {
|
|
567
|
+
ca_free(t->blanks[k]);
|
|
568
|
+
t->blanks[k] = NULL;
|
|
479
569
|
}
|
|
480
570
|
}
|
|
481
571
|
|
|
572
|
+
static VALUE
|
|
573
|
+
ca_mp_trial_restore (VALUE p)
|
|
574
|
+
{
|
|
575
|
+
ca_mp_trial_t *t = (ca_mp_trial_t *) p;
|
|
576
|
+
CAMultiParent *mp = (CAMultiParent *) t->mask;
|
|
577
|
+
int32_t k;
|
|
578
|
+
for ( k = 0; k < t->n; k++ ) {
|
|
579
|
+
mp->parents[k] = t->saved[k];
|
|
580
|
+
}
|
|
581
|
+
CAVIEW(t->mask)->parent = t->saved_parent;
|
|
582
|
+
if ( ! t->finished ) {
|
|
583
|
+
ca_mp_trial_free_blanks(t);
|
|
584
|
+
}
|
|
585
|
+
return Qnil;
|
|
586
|
+
}
|
|
587
|
+
|
|
482
588
|
void
|
|
483
|
-
|
|
484
|
-
|
|
589
|
+
ca_multi_parent_mask_refuse_first (CArray *mask, CArray **parents,
|
|
590
|
+
CArray **standins, int32_t n,
|
|
591
|
+
VALUE (*body)(VALUE), VALUE arg)
|
|
485
592
|
{
|
|
486
593
|
CAMultiParent *mp = (CAMultiParent *) mask;
|
|
487
|
-
|
|
594
|
+
volatile VALUE h_blank = 0, h_saved = 0;
|
|
595
|
+
ca_mp_trial_t t;
|
|
596
|
+
int32_t k, refused = -1;
|
|
488
597
|
if ( standins == NULL ) {
|
|
489
598
|
return;
|
|
490
599
|
}
|
|
491
600
|
for ( k = 0; k < n; k++ ) {
|
|
492
|
-
|
|
601
|
+
if ( standins[k] != NULL && mp->parents[k] == standins[k]
|
|
602
|
+
&& ca_mask_standin_parent_unmaskable(parents[k]) ) {
|
|
603
|
+
break;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if ( k == n ) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
t.mask = mask;
|
|
610
|
+
t.n = n;
|
|
611
|
+
t.finished = 0;
|
|
612
|
+
t.body = body;
|
|
613
|
+
t.arg = arg;
|
|
614
|
+
t.saved_parent = CAVIEW(mask)->parent;
|
|
615
|
+
t.blanks = ALLOCV_N(CArray *, h_blank, n);
|
|
616
|
+
t.saved = ALLOCV_N(CArray *, h_saved, n);
|
|
617
|
+
for ( k = 0; k < n; k++ ) {
|
|
618
|
+
t.blanks[k] = NULL;
|
|
619
|
+
}
|
|
620
|
+
for ( k = 0; k < n; k++ ) {
|
|
621
|
+
CArray *m = mp->parents[k];
|
|
622
|
+
t.saved[k] = m;
|
|
623
|
+
t.blanks[k] = carray_new(CA_BOOLEAN, m->ndim, m->dim, 0, NULL);
|
|
624
|
+
MEMZERO(t.blanks[k]->ptr, boolean8_t, t.blanks[k]->elements);
|
|
625
|
+
}
|
|
626
|
+
for ( k = 0; k < n; k++ ) {
|
|
627
|
+
mp->parents[k] = t.blanks[k];
|
|
628
|
+
}
|
|
629
|
+
CAVIEW(mask)->parent = t.blanks[0];
|
|
630
|
+
rb_ensure(ca_mp_trial_body, (VALUE) &t, ca_mp_trial_restore, (VALUE) &t);
|
|
631
|
+
for ( k = 0; k < n && refused < 0; k++ ) {
|
|
632
|
+
CArray *z = t.blanks[k];
|
|
493
633
|
ca_size_t i;
|
|
494
|
-
if (
|
|
495
|
-
|| !
|
|
634
|
+
if ( standins[k] == NULL || t.saved[k] != standins[k]
|
|
635
|
+
|| ! ca_mask_standin_parent_unmaskable(parents[k]) ) {
|
|
496
636
|
continue;
|
|
497
637
|
}
|
|
498
638
|
for ( i = 0; i < z->elements && ! ((boolean8_t *) z->ptr)[i]; i++ ) ;
|
|
499
|
-
if ( i
|
|
500
|
-
|
|
639
|
+
if ( i < z->elements ) {
|
|
640
|
+
refused = k;
|
|
501
641
|
}
|
|
502
|
-
|
|
642
|
+
}
|
|
643
|
+
ca_mp_trial_free_blanks(&t);
|
|
644
|
+
ALLOCV_END(h_blank);
|
|
645
|
+
ALLOCV_END(h_saved);
|
|
646
|
+
if ( refused >= 0 ) {
|
|
503
647
|
rb_raise(rb_eTypeError, "can not create mask array for the %s array",
|
|
504
|
-
ca_is_value_array(parents[
|
|
648
|
+
ca_is_value_array(parents[refused]) ? "value" : "mask");
|
|
505
649
|
}
|
|
506
650
|
}
|
|
507
651
|
|
|
@@ -510,26 +654,20 @@ ca_multi_parent_mask_settle (CArray *mask, CArray **parents,
|
|
|
510
654
|
CArray **standins, int32_t n)
|
|
511
655
|
{
|
|
512
656
|
CAMultiParent *mp = (CAMultiParent *) mask;
|
|
513
|
-
int32_t k;
|
|
657
|
+
int32_t k, pass;
|
|
514
658
|
if ( standins == NULL ) {
|
|
515
659
|
return;
|
|
516
660
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
for ( i = 0; i < z->elements && ! ((boolean8_t *) z->ptr)[i]; i++ ) ;
|
|
527
|
-
if ( i == z->elements ) {
|
|
528
|
-
continue;
|
|
661
|
+
/* The parts that can have no mask first, so that a refused true leaves
|
|
662
|
+
the other parts as they were. */
|
|
663
|
+
for ( pass = 0; pass < 2; pass++ ) {
|
|
664
|
+
for ( k = 0; k < n; k++ ) {
|
|
665
|
+
if ( standins[k] == NULL || mp->parents[k] != standins[k]
|
|
666
|
+
|| ca_mask_standin_parent_unmaskable(parents[k]) != ( pass == 0 ) ) {
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
ca_mask_standin_settle(parents[k], standins[k]);
|
|
529
670
|
}
|
|
530
|
-
ca_create_mask(parents[k]);
|
|
531
|
-
ca_xfer_all(parents[k]->mask, z->ptr, CA_XFER_PUT);
|
|
532
|
-
MEMZERO(z->ptr, boolean8_t, z->elements);
|
|
533
671
|
}
|
|
534
672
|
}
|
|
535
673
|
|
|
@@ -553,6 +691,10 @@ ca_create_mask (void *ap)
|
|
|
553
691
|
}
|
|
554
692
|
|
|
555
693
|
ca_func[ca->obj_type].create_mask(ca);
|
|
694
|
+
if ( ! ca->mask ) {
|
|
695
|
+
/* a lazy expression with no masked operand has no mask to make */
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
556
698
|
ca_set_flag(ca->mask, CA_FLAG_MASK_ARRAY); /* set array as mask array */
|
|
557
699
|
if ( ca_is_view(ca) ) {
|
|
558
700
|
if ( CAVIEW(ca)->attach ) {
|
|
@@ -561,6 +703,7 @@ ca_create_mask (void *ap)
|
|
|
561
703
|
then comes off again, since the view's sync and detach would
|
|
562
704
|
find it attached to nothing. */
|
|
563
705
|
int tag = 0;
|
|
706
|
+
/* protect: the mask comes off its view before it is freed */
|
|
564
707
|
rb_protect(ca_create_mask_attach, (VALUE) ca->mask, &tag);
|
|
565
708
|
if ( tag ) {
|
|
566
709
|
CArray *mask = ca->mask;
|
|
@@ -606,6 +749,13 @@ ca_setup_mask (void *ap, CArray *mask)
|
|
|
606
749
|
{
|
|
607
750
|
CArray *ca = (CArray *) ap;
|
|
608
751
|
|
|
752
|
+
if ( mask ) {
|
|
753
|
+
if ( ! ca_is_boolean_type(mask) ) {
|
|
754
|
+
rb_raise(rb_eCADataTypeError, "a mask is a boolean array");
|
|
755
|
+
}
|
|
756
|
+
ca_check_same_elements(ca, mask);
|
|
757
|
+
}
|
|
758
|
+
|
|
609
759
|
ca_update_mask(ca);
|
|
610
760
|
|
|
611
761
|
if ( mask ) {
|
|
@@ -685,6 +835,21 @@ ca_copy_mask_overlay_core (CArray *ca, ca_size_t elements, int n,
|
|
|
685
835
|
char *modes;
|
|
686
836
|
int i, some_has_mask = 0;
|
|
687
837
|
|
|
838
|
+
if ( elements > ca->elements ) {
|
|
839
|
+
elements = ca->elements;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/* An array source is read cell by cell over the destination's cells;
|
|
843
|
+
a scalar source's one cell applies to all of them. */
|
|
844
|
+
for (i=0; i<n; i++) {
|
|
845
|
+
cs = slist[i];
|
|
846
|
+
if ( cs && ! ca_is_scalar(cs) && cs->elements < elements ) {
|
|
847
|
+
rb_raise(rb_eArgError,
|
|
848
|
+
"mask source has %lld elements, fewer than the %lld of the destination",
|
|
849
|
+
(long long) cs->elements, (long long) elements);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
688
853
|
for (i=0; i<n; i++) {
|
|
689
854
|
if ( slist[i] && ca_has_mask(slist[i]) ) {
|
|
690
855
|
some_has_mask = 1;
|
|
@@ -703,10 +868,6 @@ ca_copy_mask_overlay_core (CArray *ca, ca_size_t elements, int n,
|
|
|
703
868
|
return;
|
|
704
869
|
}
|
|
705
870
|
|
|
706
|
-
if ( elements > ca->elements ) {
|
|
707
|
-
elements = ca->elements;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
871
|
o.list = ALLOCA_N(CArray *, n + 1);
|
|
711
872
|
o.snap = ALLOCA_N(boolean8_t *, n);
|
|
712
873
|
o.att = ALLOCA_N(CArray *, n);
|
|
@@ -900,6 +1061,10 @@ ca_unmask (void *ap, char *fill_value)
|
|
|
900
1061
|
{
|
|
901
1062
|
CArray *ca = (CArray *) ap;
|
|
902
1063
|
|
|
1064
|
+
if ( ca_is_readonly(ca) ) {
|
|
1065
|
+
ca_refuse_read_only();
|
|
1066
|
+
}
|
|
1067
|
+
|
|
903
1068
|
ca_update_mask(ca);
|
|
904
1069
|
if ( ca->mask ) {
|
|
905
1070
|
if ( ! fill_value ) {
|
|
@@ -1258,6 +1423,72 @@ rb_ca_mask_array (VALUE self)
|
|
|
1258
1423
|
}
|
|
1259
1424
|
}
|
|
1260
1425
|
|
|
1426
|
+
/* dup / clone of a mask. The mask of a view is a view over its parent's
|
|
1427
|
+
mask, and its dup, like the dup of any view, is another view onto the
|
|
1428
|
+
same parent mask: it follows later changes and a write to it lands in
|
|
1429
|
+
the parent's mask (copy makes a mask of its own). A mask over a cast, a
|
|
1430
|
+
byte swap, a Face or a lazy expression is shown as CArrayMask, whose
|
|
1431
|
+
allocator makes an entity, so Object#dup would copy its cells; it is
|
|
1432
|
+
rebuilt here from its own view instead. The mask of an entity is an
|
|
1433
|
+
entity and is copied. */
|
|
1434
|
+
static VALUE
|
|
1435
|
+
ca_mask_view_dup (VALUE self)
|
|
1436
|
+
{
|
|
1437
|
+
volatile VALUE obj;
|
|
1438
|
+
const rb_data_type_t *type;
|
|
1439
|
+
CArray *ca, *cp;
|
|
1440
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1441
|
+
cp = (CArray *) ca_func[ca->obj_type].clone(ca);
|
|
1442
|
+
ca_keep_chain_flags(cp, ca);
|
|
1443
|
+
type = ca_typeddata[ca->obj_type];
|
|
1444
|
+
if ( type->function.dfree != ca_free ) {
|
|
1445
|
+
type = &carray_data_type; /* the copy is this object's to free */
|
|
1446
|
+
}
|
|
1447
|
+
obj = TypedData_Wrap_Struct(rb_obj_class(self), type, cp);
|
|
1448
|
+
rb_ivar_set(obj, rb_intern("masked_array"),
|
|
1449
|
+
rb_ivar_get(self, rb_intern("masked_array")));
|
|
1450
|
+
return obj;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
static VALUE
|
|
1454
|
+
rb_ca_mask_dup (VALUE self)
|
|
1455
|
+
{
|
|
1456
|
+
CArray *ca;
|
|
1457
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1458
|
+
if ( ! ca_is_view(ca) ) {
|
|
1459
|
+
return rb_call_super(0, NULL);
|
|
1460
|
+
}
|
|
1461
|
+
return ca_mask_view_dup(self);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
static VALUE
|
|
1465
|
+
rb_ca_mask_clone (int argc, VALUE *argv, VALUE self)
|
|
1466
|
+
{
|
|
1467
|
+
VALUE opts = Qnil, vfreeze = Qnil;
|
|
1468
|
+
volatile VALUE obj;
|
|
1469
|
+
CArray *ca;
|
|
1470
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1471
|
+
if ( ! ca_is_view(ca) ) {
|
|
1472
|
+
return rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
|
|
1473
|
+
}
|
|
1474
|
+
rb_scan_args(argc, argv, "0:", &opts);
|
|
1475
|
+
if ( ! NIL_P(opts) ) {
|
|
1476
|
+
/* rb_get_kwargs refuses any key but freeze:, as Kernel#clone does. */
|
|
1477
|
+
ID kw[1];
|
|
1478
|
+
VALUE val[1];
|
|
1479
|
+
kw[0] = rb_intern("freeze");
|
|
1480
|
+
rb_get_kwargs(opts, kw, 0, 1, val);
|
|
1481
|
+
if ( val[0] != Qundef ) {
|
|
1482
|
+
vfreeze = val[0];
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
obj = ca_mask_view_dup(self);
|
|
1486
|
+
if ( RTEST(vfreeze) || ( NIL_P(vfreeze) && OBJ_FROZEN(self) ) ) {
|
|
1487
|
+
rb_obj_freeze(obj);
|
|
1488
|
+
}
|
|
1489
|
+
return obj;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1261
1492
|
/* @overload mask= (new_mask)
|
|
1262
1493
|
|
|
1263
1494
|
(Mask, Modification)
|
|
@@ -1491,14 +1722,9 @@ rb_ca_mask_fill (VALUE self, VALUE fval)
|
|
|
1491
1722
|
return rb_ca_unmask_method(1, &fval, self);
|
|
1492
1723
|
}
|
|
1493
1724
|
|
|
1494
|
-
/*
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
Returns new unmasked array.
|
|
1498
|
-
If the optional argument <code>fill_value</code> is given,
|
|
1499
|
-
the masked elements are filled by <code>fill_value</code>.
|
|
1500
|
-
The returned array doesn't have the mask array.
|
|
1501
|
-
*/
|
|
1725
|
+
/* A copy without the mask: with a fill value, the masked cells hold it.
|
|
1726
|
+
Behind rb_ca_unmask_copy / rb_ca_mask_fill_copy (C only; the Ruby
|
|
1727
|
+
surface is strip_mask). */
|
|
1502
1728
|
|
|
1503
1729
|
static VALUE
|
|
1504
1730
|
rb_ca_unmask_copy_method (int argc, VALUE *argv, VALUE self)
|
|
@@ -1654,6 +1880,19 @@ rb_ca_mask_where (int argc, VALUE *argv, VALUE self)
|
|
|
1654
1880
|
return ca_mask_copy_where(self, argc, argv);
|
|
1655
1881
|
}
|
|
1656
1882
|
|
|
1883
|
+
/* inherit_mask's sources are read cell by cell over self, so an array
|
|
1884
|
+
source has self's number of cells (a scalar's one cell applies to all). */
|
|
1885
|
+
static void
|
|
1886
|
+
ca_inherit_mask_check_source (CArray *ca, CArray *cs)
|
|
1887
|
+
{
|
|
1888
|
+
if ( ! ca_is_scalar(cs) && cs->elements != ca->elements ) {
|
|
1889
|
+
rb_raise(rb_eArgError,
|
|
1890
|
+
"%s: mask source has %lld elements, the receiver %lld",
|
|
1891
|
+
ca_calling_method_name(),
|
|
1892
|
+
(long long) cs->elements, (long long) ca->elements);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1657
1896
|
/* @overload inherit_mask (*others):
|
|
1658
1897
|
|
|
1659
1898
|
(Masking, Destructive)
|
|
@@ -1677,6 +1916,7 @@ rb_ca_inherit_mask_method (int argc, VALUE *argv, VALUE self)
|
|
|
1677
1916
|
for (i=0; i<argc; i++) {
|
|
1678
1917
|
if ( rb_obj_is_carray(argv[i]) ) {
|
|
1679
1918
|
TypedData_Get_Struct(argv[i], CArray, &carray_data_type, cs);
|
|
1919
|
+
ca_inherit_mask_check_source(ca, cs);
|
|
1680
1920
|
slist[i] = cs;
|
|
1681
1921
|
}
|
|
1682
1922
|
else {
|
|
@@ -1720,6 +1960,7 @@ rb_ca_inherit_mask (VALUE self, int n, ...)
|
|
|
1720
1960
|
other = va_arg(rothers, VALUE);
|
|
1721
1961
|
if ( rb_obj_is_carray(other) ) {
|
|
1722
1962
|
TypedData_Get_Struct(other, CArray, &carray_data_type, cs);
|
|
1963
|
+
ca_inherit_mask_check_source(ca, cs);
|
|
1723
1964
|
slist[i] = cs;
|
|
1724
1965
|
}
|
|
1725
1966
|
else {
|
|
@@ -1758,6 +1999,7 @@ rb_ca_inherit_mask_replace_method (int argc, VALUE *argv, VALUE self)
|
|
|
1758
1999
|
for (i=0; i<argc; i++) {
|
|
1759
2000
|
if ( rb_obj_is_carray(argv[i]) ) {
|
|
1760
2001
|
TypedData_Get_Struct(argv[i], CArray, &carray_data_type, cs);
|
|
2002
|
+
ca_inherit_mask_check_source(ca, cs);
|
|
1761
2003
|
slist[i] = cs;
|
|
1762
2004
|
}
|
|
1763
2005
|
else {
|
|
@@ -1801,6 +2043,7 @@ rb_ca_inherit_mask_replace (VALUE self, int n, ...)
|
|
|
1801
2043
|
other = va_arg(rothers, VALUE);
|
|
1802
2044
|
if ( rb_obj_is_carray(other) ) {
|
|
1803
2045
|
TypedData_Get_Struct(other, CArray, &carray_data_type, cs);
|
|
2046
|
+
ca_inherit_mask_check_source(ca, cs);
|
|
1804
2047
|
slist[i] = cs;
|
|
1805
2048
|
}
|
|
1806
2049
|
else {
|
|
@@ -2048,11 +2291,9 @@ ca_binop_bit_or_i_boolean8_fast (ca_size_t n, boolean8_t *m,
|
|
|
2048
2291
|
accumulating; here we need 3-arg). */
|
|
2049
2292
|
ca_size_t nw = n / CA_MASK_WORD_BYTES;
|
|
2050
2293
|
ca_size_t j;
|
|
2051
|
-
uint64_t *wd = (uint64_t *) q3;
|
|
2052
|
-
const uint64_t *wa = (const uint64_t *) q1;
|
|
2053
|
-
const uint64_t *wb = (const uint64_t *) q2;
|
|
2054
2294
|
for (j = 0; j < nw; j++) {
|
|
2055
|
-
|
|
2295
|
+
ca_mask_word_store(q3 + j*CA_MASK_WORD_BYTES,
|
|
2296
|
+
ca_mask_word_load(q1 + j*CA_MASK_WORD_BYTES) | ca_mask_word_load(q2 + j*CA_MASK_WORD_BYTES));
|
|
2056
2297
|
}
|
|
2057
2298
|
for (j = nw * CA_MASK_WORD_BYTES; j < n; j++) {
|
|
2058
2299
|
q3[j] = q1[j] | q2[j];
|
|
@@ -2202,7 +2443,7 @@ rb_ca_inherit_mask_replace_ruby (int argc, VALUE *argv, VALUE self)
|
|
|
2202
2443
|
void
|
|
2203
2444
|
Init_carray_mask (void)
|
|
2204
2445
|
{
|
|
2205
|
-
rb_define_private_method(rb_cCArray, "
|
|
2446
|
+
rb_define_private_method(rb_cCArray, "add_mask", rb_ca_create_mask, 0);
|
|
2206
2447
|
/*
|
|
2207
2448
|
rb_define_private_method(rb_cCArray, "__update_mask__", rb_ca_update_mask, 0);
|
|
2208
2449
|
*/
|
|
@@ -2213,6 +2454,8 @@ Init_carray_mask (void)
|
|
|
2213
2454
|
|
|
2214
2455
|
rb_define_method(rb_cCArray, "value", rb_ca_value_array, 0);
|
|
2215
2456
|
rb_define_method(rb_cCArray, "mask", rb_ca_mask_array, 0);
|
|
2457
|
+
rb_define_method(rb_cCArrayMask, "dup", rb_ca_mask_dup, 0);
|
|
2458
|
+
rb_define_method(rb_cCArrayMask, "clone", rb_ca_mask_clone, -1);
|
|
2216
2459
|
rb_define_method(rb_cCArray, "mask=", rb_ca_set_mask, 1);
|
|
2217
2460
|
rb_define_method(rb_cCArray, "is_masked", rb_ca_is_masked, 0);
|
|
2218
2461
|
rb_define_method(rb_cCArray, "is_not_masked", rb_ca_is_not_masked, 0);
|