carray 3.0.3 → 3.0.4
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 +264 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +1 -6
- 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 +205 -134
- data/ext/ca_compare.c +7 -18
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1234 -1994
- data/ext/ca_kernel_iterator.h +391 -437
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +96 -39
- data/ext/ca_obj_bincmp.c +24 -21
- data/ext/ca_obj_binop.c +15 -26
- data/ext/ca_obj_bitarray.c +3 -2
- data/ext/ca_obj_bitfield.c +5 -6
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +5 -6
- data/ext/ca_obj_const_string.c +173 -19
- data/ext/ca_obj_face.c +238 -57
- 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 +17 -5
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +406 -132
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +67 -57
- data/ext/ca_obj_object.c +157 -51
- data/ext/ca_obj_record.c +12 -7
- data/ext/ca_obj_reduce.c +13 -8
- data/ext/ca_obj_refer.c +25 -27
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +6 -5
- data/ext/ca_obj_select.c +14 -9
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +11 -1
- data/ext/ca_obj_stack.c +179 -34
- data/ext/ca_obj_stride.c +162 -115
- data/ext/ca_obj_string.c +71 -4
- data/ext/ca_obj_tile.c +6 -5
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +5 -3
- data/ext/ca_obj_triop.c +23 -32
- data/ext/ca_obj_window.c +190 -26
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +181 -75
- data/ext/carray_access.c +184 -96
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +89 -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 +142 -24
- data/ext/carray_cast_func.rb +46 -6
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +16 -7
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +147 -55
- data/ext/carray_count.c +50 -20
- data/ext/carray_element.c +76 -33
- data/ext/carray_factorize.c +118 -64
- data/ext/carray_generate.c +191 -50
- data/ext/carray_histogram.c +62 -17
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +336 -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 +10906 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +292 -72
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +124 -47
- data/ext/carray_order.c +384 -76
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +67 -13
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +63 -38
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +91 -28
- data/ext/carray_sort.c +35 -35
- data/ext/carray_struct.c +19 -18
- data/ext/carray_test.c +26 -5
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +246 -45
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +198 -240
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +126 -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 +78 -10
- 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 +165 -43
- data/lib/carray/categorical_iterator.rb +130 -27
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +14 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- 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 +246 -21
- data/lib/carray/frame/group.rb +510 -95
- data/lib/carray/frame/io.rb +115 -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 +11 -4
- 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 +182 -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 +53 -36
- 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 +313 -82
- data/lib/carray/serialize.rb +24 -10
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +8 -1
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +19 -8
- data/lib/carray/time.rb +726 -104
- 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_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_cast.rb +10 -0
- data/yard-stubs/carray_conversion.rb +2 -1
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +26 -2
- data/yard-stubs/carray_math.rb +27 -1
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +29 -18
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +14 -9
- 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/ca_obj_face.c
CHANGED
|
@@ -132,10 +132,18 @@ rb_ca_face_template (VALUE original_face, CArray *new_parent,
|
|
|
132
132
|
TypedData_Get_Struct(original_face, CArray, &carray_data_type, src);
|
|
133
133
|
tdata = ca_typeddata[src->obj_type];
|
|
134
134
|
|
|
135
|
-
/*
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
/* The struct with its subclass tail. struct_size is the struct alone;
|
|
136
|
+
a dsize callback also counts the buffers the struct points to (dim),
|
|
137
|
+
so it is only the fallback for a type registered without struct_size,
|
|
138
|
+
and copying that many bytes reads past the struct. */
|
|
139
|
+
if ( ca_func[src->obj_type].struct_size ) {
|
|
140
|
+
size = ca_func[src->obj_type].struct_size;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
size = (tdata && tdata->function.dsize)
|
|
144
|
+
? tdata->function.dsize(src)
|
|
145
|
+
: sizeof(CAView);
|
|
146
|
+
}
|
|
139
147
|
|
|
140
148
|
dst = (CArray *) xmalloc(size);
|
|
141
149
|
/* CAREFUL: the whole-struct memcpy is how a C-tail Face
|
|
@@ -198,6 +206,23 @@ ca_face_relift_entity (VALUE face, VALUE result)
|
|
|
198
206
|
return lifted;
|
|
199
207
|
}
|
|
200
208
|
|
|
209
|
+
/* A lift moves a view built on a wrapper (a Face or the lazy marker) one
|
|
210
|
+
* level down, onto what the wrapper wraps, so the view no longer keeps the
|
|
211
|
+
* wrapper alive. The view's mask was built over the wrapper's mask, which
|
|
212
|
+
* the wrapper owns and frees with itself; move it down the same level.
|
|
213
|
+
* The wrapper's mask is a same-shape refer of its parent's mask, so the
|
|
214
|
+
* mask view addresses the same cells there. */
|
|
215
|
+
static void
|
|
216
|
+
ca_lift_move_mask_down (CArray *view_ca, CArray *wp)
|
|
217
|
+
{
|
|
218
|
+
CArray *below = ((CAView *) wp)->parent;
|
|
219
|
+
if ( view_ca->mask && wp->mask && ca_is_view(wp->mask)
|
|
220
|
+
&& ((CAView *) wp->mask)->parent == below->mask
|
|
221
|
+
&& ((CAView *) view_ca->mask)->parent == wp->mask ) {
|
|
222
|
+
((CAView *) view_ca->mask)->parent = below->mask;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
201
226
|
/* ca_face_lift(view, face_parent) — at the tail of user-facing entry
|
|
202
227
|
* points (`ca[...]` etc.), when the operand was a Face, re-wrap the
|
|
203
228
|
* resulting view as a Face of the same subclass. Thin wrapper over
|
|
@@ -260,6 +285,7 @@ ca_face_lift (VALUE view, VALUE face_parent)
|
|
|
260
285
|
&& ! ca_test_flag(view_ca, CA_FLAG_MULTI_PARENTS) ) {
|
|
261
286
|
((CAView *) view_ca)->parent = ((CAView *) fp)->parent; /* C pointer: one level */
|
|
262
287
|
rb_ca_set_parent(view, rb_ca_parent(face_parent)); /* @parent ivar: lockstep */
|
|
288
|
+
ca_lift_move_mask_down(view_ca, fp);
|
|
263
289
|
}
|
|
264
290
|
}
|
|
265
291
|
|
|
@@ -269,6 +295,12 @@ ca_face_lift (VALUE view, VALUE face_parent)
|
|
|
269
295
|
lifted = rb_ca_face_template(face_parent, view_ca, view_ca->dim);
|
|
270
296
|
/* Pin view as a GC root of lifted so the slice is not collected. */
|
|
271
297
|
rb_ca_set_parent(lifted, view);
|
|
298
|
+
/* The Face the view was taken from is off the parent chain now; keep it
|
|
299
|
+
for the attributes set on it. A fresh result the ordering kernels
|
|
300
|
+
re-wrap is not a view of it and takes none. */
|
|
301
|
+
if ( ca_is_view(view_ca) ) {
|
|
302
|
+
rb_ca_set_lifted_from(lifted, face_parent);
|
|
303
|
+
}
|
|
272
304
|
|
|
273
305
|
/* Optional Ruby callback for ivar / state carry. Faces holding
|
|
274
306
|
semantic state in the struct tail (CATime / CATimedelta
|
|
@@ -346,6 +378,7 @@ ca_lazy_marker_lift (VALUE view, VALUE marker)
|
|
|
346
378
|
&& ! ca_test_flag(view_ca, CA_FLAG_MULTI_PARENTS) ) {
|
|
347
379
|
((CAView *) view_ca)->parent = ((CAView *) mp)->parent; /* C pointer */
|
|
348
380
|
rb_ca_set_parent(view, rb_ca_parent(marker)); /* @parent ivar */
|
|
381
|
+
ca_lift_move_mask_down(view_ca, mp);
|
|
349
382
|
}
|
|
350
383
|
|
|
351
384
|
return rb_ca_lazy_marker_new(view);
|
|
@@ -522,15 +555,10 @@ ca_face_register_state_compatible (int obj_type, ca_face_state_compatible_fn fn)
|
|
|
522
555
|
static int
|
|
523
556
|
ca_face_has_ruby_state_check (VALUE va)
|
|
524
557
|
{
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
558
|
+
ID id_face_state_compatible_p = rb_intern("face_state_compatible?");
|
|
559
|
+
ID id_method = rb_intern("method");
|
|
560
|
+
ID id_owner = rb_intern("owner");
|
|
528
561
|
VALUE m, owner;
|
|
529
|
-
if ( id_face_state_compatible_p == 0 ) {
|
|
530
|
-
id_face_state_compatible_p = rb_intern("face_state_compatible?");
|
|
531
|
-
id_method = rb_intern("method");
|
|
532
|
-
id_owner = rb_intern("owner");
|
|
533
|
-
}
|
|
534
562
|
m = rb_funcall(va, id_method, 1, ID2SYM(id_face_state_compatible_p));
|
|
535
563
|
owner = rb_funcall(m, id_owner, 0);
|
|
536
564
|
return ( owner != rb_cCArray ) ? 1 : 0;
|
|
@@ -650,16 +678,11 @@ ca_face_register_state_portable (int obj_type, int portable)
|
|
|
650
678
|
static int
|
|
651
679
|
ca_face_class_has_portable_method (VALUE klass)
|
|
652
680
|
{
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
681
|
+
ID id_face_state_portable_p = rb_intern("face_state_portable?");
|
|
682
|
+
ID id_method = rb_intern("method");
|
|
683
|
+
ID id_owner = rb_intern("owner");
|
|
656
684
|
VALUE m, owner;
|
|
657
685
|
if ( NIL_P(klass) ) return 0;
|
|
658
|
-
if ( id_face_state_portable_p == 0 ) {
|
|
659
|
-
id_face_state_portable_p = rb_intern("face_state_portable?");
|
|
660
|
-
id_method = rb_intern("method");
|
|
661
|
-
id_owner = rb_intern("owner");
|
|
662
|
-
}
|
|
663
686
|
if ( !rb_respond_to(klass, id_face_state_portable_p) ) return 0;
|
|
664
687
|
m = rb_funcall(klass, id_method, 1, ID2SYM(id_face_state_portable_p));
|
|
665
688
|
owner = rb_funcall(m, id_owner, 0);
|
|
@@ -680,18 +703,88 @@ ca_face_conversion_hint (VALUE face)
|
|
|
680
703
|
: "to_type(:object) gives its values";
|
|
681
704
|
}
|
|
682
705
|
|
|
706
|
+
/* The method that gives the storage under a Face, for a refusal to point
|
|
707
|
+
at: #ticks for a time or a duration, #codes for a categorical. NULL for
|
|
708
|
+
a Face that names its storage some other way, or not at all. */
|
|
709
|
+
const char *
|
|
710
|
+
ca_face_storage_method (VALUE face)
|
|
711
|
+
{
|
|
712
|
+
static const char *names[] = { "ticks", "codes" };
|
|
713
|
+
size_t i;
|
|
714
|
+
for (i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
|
|
715
|
+
if ( rb_respond_to(face, rb_intern(names[i])) ) {
|
|
716
|
+
return names[i];
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return NULL;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/* ca.face_storage_method -- the name of the method that gives the storage
|
|
723
|
+
under ca (ca_face_storage_method), as a String, or nil. For refusals
|
|
724
|
+
written in Ruby. */
|
|
725
|
+
static VALUE
|
|
726
|
+
rb_ca_face_storage_method (VALUE self)
|
|
727
|
+
{
|
|
728
|
+
const char *name = ca_face_storage_method(self);
|
|
729
|
+
return name ? rb_str_new_cstr(name) : Qnil;
|
|
730
|
+
}
|
|
731
|
+
|
|
683
732
|
/* Refuse to order (or, with verb "count", to count by value) a Face whose
|
|
684
733
|
storage does not hold its values in order, pointing at what does: its
|
|
685
734
|
values, or its storage when that is what is meant. */
|
|
686
735
|
void
|
|
687
736
|
ca_face_refuse_order (const char *name, VALUE face, const char *verb)
|
|
688
737
|
{
|
|
738
|
+
const char *storage = ca_face_storage_method(face);
|
|
739
|
+
if ( storage ) {
|
|
740
|
+
rb_raise(rb_eArgError,
|
|
741
|
+
"%s: %s is not orderable by storage (a cell encodes the value "
|
|
742
|
+
"rather than being it); %s its values instead -- %s -- or %s "
|
|
743
|
+
"its storage, which #%s gives",
|
|
744
|
+
name, rb_obj_classname(face), verb,
|
|
745
|
+
ca_face_conversion_hint(face), verb, storage);
|
|
746
|
+
}
|
|
689
747
|
rb_raise(rb_eArgError,
|
|
690
748
|
"%s: %s is not orderable by storage (a cell encodes the value "
|
|
691
|
-
"rather than being it); %s its values instead -- %s
|
|
692
|
-
".parent to %s its storage",
|
|
749
|
+
"rather than being it); %s its values instead -- %s",
|
|
693
750
|
name, rb_obj_classname(face), verb,
|
|
694
|
-
ca_face_conversion_hint(face)
|
|
751
|
+
ca_face_conversion_hint(face));
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/* The rule every family that orders, compares, searches or hashes the cells
|
|
755
|
+
of a Face reference keeps: the storage stands for the values only when the
|
|
756
|
+
Face declares ORDERABLE_STORAGE. A fixlen storage is no exception -- its
|
|
757
|
+
bytes are an order only when the Face says so (CAFixlenString). Returns
|
|
758
|
+
when the Face is ORDERABLE; refuses otherwise (ca_face_refuse_order). A
|
|
759
|
+
family that can order by a key asks ca_face_orders_by_itself first. */
|
|
760
|
+
void
|
|
761
|
+
ca_face_require_orderable (VALUE face, const char *name, const char *verb)
|
|
762
|
+
{
|
|
763
|
+
CArray *ca;
|
|
764
|
+
TypedData_Get_Struct(face, CArray, &carray_data_type, ca);
|
|
765
|
+
if ( ! ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
766
|
+
ca_face_refuse_order(name, face, verb);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/* Whether a Face is ordered by its own #order rather than by its storage:
|
|
771
|
+
it is not ORDERABLE and answers #order itself (CAConstString, CARecord),
|
|
772
|
+
so a family that orders by a key can take that order. CArray#order is
|
|
773
|
+
not one: it sorts the storage and comes back to the gate. */
|
|
774
|
+
int
|
|
775
|
+
ca_face_orders_by_itself (VALUE face)
|
|
776
|
+
{
|
|
777
|
+
ID id_order = rb_intern("order");
|
|
778
|
+
ID id_method = rb_intern("method");
|
|
779
|
+
ID id_owner = rb_intern("owner");
|
|
780
|
+
CArray *ca;
|
|
781
|
+
VALUE m;
|
|
782
|
+
TypedData_Get_Struct(face, CArray, &carray_data_type, ca);
|
|
783
|
+
if ( ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
784
|
+
return 0;
|
|
785
|
+
}
|
|
786
|
+
m = rb_funcall(face, id_method, 1, ID2SYM(id_order));
|
|
787
|
+
return ( rb_funcall(m, id_owner, 0) != rb_cCArray ) ? 1 : 0;
|
|
695
788
|
}
|
|
696
789
|
|
|
697
790
|
/* Refuse a numeric operation (arithmetic, math, a reduction) on a Face,
|
|
@@ -708,10 +801,20 @@ ca_face_refuse_numeric (VALUE self, const char *name, VALUE eclass)
|
|
|
708
801
|
if ( ! ca_is_face(ca) ) {
|
|
709
802
|
return;
|
|
710
803
|
}
|
|
804
|
+
{
|
|
805
|
+
const char *storage = ca_face_storage_method(self);
|
|
806
|
+
if ( storage ) {
|
|
807
|
+
rb_raise(eclass,
|
|
808
|
+
"%s: %s does not define it (a cell encodes the value rather "
|
|
809
|
+
"than being a number); compute on its values instead -- %s -- "
|
|
810
|
+
"or on its storage, which #%s gives",
|
|
811
|
+
name, rb_obj_classname(self), ca_face_conversion_hint(self),
|
|
812
|
+
storage);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
711
815
|
rb_raise(eclass,
|
|
712
816
|
"%s: %s does not define it (a cell encodes the value rather than "
|
|
713
|
-
"being a number); compute on its values instead -- %s
|
|
714
|
-
".parent to compute on its storage",
|
|
817
|
+
"being a number); compute on its values instead -- %s",
|
|
715
818
|
name, rb_obj_classname(self), ca_face_conversion_hint(self));
|
|
716
819
|
}
|
|
717
820
|
|
|
@@ -729,12 +832,24 @@ ca_face_operand_descend (VALUE operand, const char *name)
|
|
|
729
832
|
if ( ca_test_flag(op, CA_FLAG_FACE_COMPARABLE_STORAGE) ) {
|
|
730
833
|
return rb_ca_strip_face_value(operand);
|
|
731
834
|
}
|
|
835
|
+
{
|
|
836
|
+
const char *storage = ca_face_storage_method(operand);
|
|
837
|
+
if ( storage ) {
|
|
838
|
+
rb_raise(rb_eArgError,
|
|
839
|
+
"%s: cannot take a %s operand: its storage is not its surface "
|
|
840
|
+
"(a cell encodes the value rather than being it), so comparing "
|
|
841
|
+
"the storage would compare the encoding. Convert the operand "
|
|
842
|
+
"to the receiver's space first -- %s -- or compare the storage "
|
|
843
|
+
"of both sides, which #%s gives",
|
|
844
|
+
name, rb_obj_classname(operand),
|
|
845
|
+
ca_face_conversion_hint(operand), storage);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
732
848
|
rb_raise(rb_eArgError,
|
|
733
849
|
"%s: cannot take a %s operand: its storage is not its surface "
|
|
734
850
|
"(a cell encodes the value rather than being it), so comparing "
|
|
735
851
|
"the storage would compare the encoding. Convert the operand to "
|
|
736
|
-
"the receiver's space first -- %s
|
|
737
|
-
"or pass .parent on both sides to work in storage space",
|
|
852
|
+
"the receiver's space first -- %s",
|
|
738
853
|
name, rb_obj_classname(operand), ca_face_conversion_hint(operand));
|
|
739
854
|
return Qnil; /* not reached */
|
|
740
855
|
}
|
|
@@ -823,11 +938,16 @@ ca_face_operand_values (VALUE operand)
|
|
|
823
938
|
- A reference with to_comparable brings any operand into its own space
|
|
824
939
|
(a unit, an instant), and refuses what it cannot convert.
|
|
825
940
|
- Any other reference has no way to read the operand in its space, and
|
|
826
|
-
refuses it.
|
|
941
|
+
refuses it.
|
|
942
|
+
UNDEF is undefined in every space, so it passes as it is and the entry
|
|
943
|
+
answers it as it does for a plain array. */
|
|
827
944
|
VALUE
|
|
828
945
|
ca_face_reconcile_operand (VALUE reference, VALUE operand, const char *name)
|
|
829
946
|
{
|
|
830
947
|
CArray *ca;
|
|
948
|
+
if ( operand == CA_UNDEF ) {
|
|
949
|
+
return operand;
|
|
950
|
+
}
|
|
831
951
|
TypedData_Get_Struct(reference, CArray, &carray_data_type, ca);
|
|
832
952
|
if ( ca->obj_type == CA_OBJ_RECORD ) {
|
|
833
953
|
if ( RTEST(rb_obj_is_carray(operand)) ) {
|
|
@@ -854,22 +974,61 @@ ca_face_reconcile_operand (VALUE reference, VALUE operand, const char *name)
|
|
|
854
974
|
if ( ca_test_flag(ca, CA_FLAG_FACE_COMPARABLE_STORAGE) ) {
|
|
855
975
|
return ca_face_operand_descend(ca_face_operand_values(operand), name);
|
|
856
976
|
}
|
|
857
|
-
|
|
858
|
-
ca_face_refuse_order(name, reference, "compare");
|
|
859
|
-
}
|
|
977
|
+
ca_face_require_orderable(reference, name, "compare");
|
|
860
978
|
if ( rb_respond_to(reference, rb_intern("to_comparable")) ) {
|
|
861
979
|
return rb_ca_strip_face_value(rb_funcall(reference,
|
|
862
980
|
rb_intern("to_comparable"),
|
|
863
981
|
1, operand));
|
|
864
982
|
}
|
|
983
|
+
{
|
|
984
|
+
const char *storage = ca_face_storage_method(reference);
|
|
985
|
+
if ( storage ) {
|
|
986
|
+
rb_raise(rb_eArgError,
|
|
987
|
+
"%s: %s is not comparable by storage and has no to_comparable "
|
|
988
|
+
"to bring the operand into its space; compare the storage of "
|
|
989
|
+
"both sides, which #%s gives",
|
|
990
|
+
name, rb_obj_classname(reference), storage);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
865
993
|
rb_raise(rb_eArgError,
|
|
866
994
|
"%s: %s is not comparable by storage and has no to_comparable "
|
|
867
|
-
"to bring the operand into its space
|
|
868
|
-
"sides to work in storage space",
|
|
995
|
+
"to bring the operand into its space",
|
|
869
996
|
name, rb_obj_classname(reference));
|
|
870
997
|
return Qnil; /* not reached */
|
|
871
998
|
}
|
|
872
999
|
|
|
1000
|
+
/* The reference and the operand of a comparison (an operator, count(v), a
|
|
1001
|
+
search, linear_section) brought into one space. A time reference answers
|
|
1002
|
+
both through comparable_pair: it keeps itself when the operand sits on its
|
|
1003
|
+
grid, and otherwise meets the operand in the finer unit the two share,
|
|
1004
|
+
where to_comparable would refuse a value off its grid. Every other
|
|
1005
|
+
reference keeps itself and reconciles the operand
|
|
1006
|
+
(ca_face_reconcile_operand). An assignment, which has to land on the
|
|
1007
|
+
reference's grid, uses ca_face_reconcile_operand. */
|
|
1008
|
+
void
|
|
1009
|
+
ca_face_reconcile_pair (volatile VALUE *pref, volatile VALUE *poperand,
|
|
1010
|
+
const char *name)
|
|
1011
|
+
{
|
|
1012
|
+
static ID id_comparable_pair = 0;
|
|
1013
|
+
VALUE ref = *pref, operand = *poperand;
|
|
1014
|
+
CArray *ca;
|
|
1015
|
+
if ( id_comparable_pair == 0 ) {
|
|
1016
|
+
id_comparable_pair = rb_intern("comparable_pair");
|
|
1017
|
+
}
|
|
1018
|
+
TypedData_Get_Struct(ref, CArray, &carray_data_type, ca);
|
|
1019
|
+
if ( operand != CA_UNDEF
|
|
1020
|
+
&& ca->obj_type != CA_OBJ_RECORD
|
|
1021
|
+
&& ! ca_test_flag(ca, CA_FLAG_FACE_COMPARABLE_STORAGE)
|
|
1022
|
+
&& ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE)
|
|
1023
|
+
&& rb_respond_to(ref, id_comparable_pair) ) {
|
|
1024
|
+
VALUE pair = rb_funcall(ref, id_comparable_pair, 1, operand);
|
|
1025
|
+
*pref = rb_ary_entry(pair, 0);
|
|
1026
|
+
*poperand = rb_ca_strip_face_value(rb_ary_entry(pair, 1));
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
*poperand = ca_face_reconcile_operand(ref, operand, name);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
873
1032
|
int
|
|
874
1033
|
ca_face_state_portable (int obj_type, VALUE klass)
|
|
875
1034
|
{
|
|
@@ -891,7 +1050,7 @@ ca_face_list_class (VALUE list, const char *who)
|
|
|
891
1050
|
{
|
|
892
1051
|
long n = RARRAY_LEN(list), i;
|
|
893
1052
|
int any_face = 0, all_face = 1;
|
|
894
|
-
VALUE face_class = Qnil;
|
|
1053
|
+
VALUE face_class = Qnil, face = Qnil;
|
|
895
1054
|
CArray *ref = NULL;
|
|
896
1055
|
|
|
897
1056
|
for ( i = 0; i < n; i++ ) {
|
|
@@ -903,6 +1062,7 @@ ca_face_list_class (VALUE list, const char *who)
|
|
|
903
1062
|
any_face = 1;
|
|
904
1063
|
if ( NIL_P(face_class) ) {
|
|
905
1064
|
face_class = rb_obj_class(p);
|
|
1065
|
+
face = p;
|
|
906
1066
|
ref = ca;
|
|
907
1067
|
}
|
|
908
1068
|
else if ( rb_obj_class(p) != face_class ) {
|
|
@@ -911,19 +1071,36 @@ ca_face_list_class (VALUE list, const char *who)
|
|
|
911
1071
|
}
|
|
912
1072
|
if ( ! any_face ) return Qnil;
|
|
913
1073
|
if ( ! all_face ) {
|
|
1074
|
+
const char *storage = ca_face_storage_method(face);
|
|
1075
|
+
if ( ref->obj_type == CA_OBJ_STRING ) {
|
|
1076
|
+
rb_raise(rb_eArgError,
|
|
1077
|
+
"%s: cannot mix Face and non-Face arrays, or arrays of "
|
|
1078
|
+
"different Face classes; convert them first to one Face "
|
|
1079
|
+
"class or to no Face (CArray.string(a) makes a CAString of "
|
|
1080
|
+
"an object array of Strings)",
|
|
1081
|
+
who);
|
|
1082
|
+
}
|
|
1083
|
+
if ( storage ) {
|
|
1084
|
+
rb_raise(rb_eArgError,
|
|
1085
|
+
"%s: cannot mix Face and non-Face arrays, or arrays of "
|
|
1086
|
+
"different Face classes; convert them first to one Face "
|
|
1087
|
+
"class or to no Face, or combine their storage (#%s gives "
|
|
1088
|
+
"the storage of a %s)",
|
|
1089
|
+
who, storage, rb_obj_classname(face));
|
|
1090
|
+
}
|
|
914
1091
|
rb_raise(rb_eArgError,
|
|
915
1092
|
"%s: cannot mix Face and non-Face arrays, or arrays of "
|
|
916
|
-
"different Face classes; convert them to one Face
|
|
917
|
-
"
|
|
1093
|
+
"different Face classes; convert them first to one Face "
|
|
1094
|
+
"class or to no Face",
|
|
918
1095
|
who);
|
|
919
1096
|
}
|
|
920
1097
|
if ( n > 1 && ! ca_face_state_portable(ref->obj_type, face_class) ) {
|
|
921
1098
|
rb_raise(rb_eArgError,
|
|
922
1099
|
"%s: %s state is not portable across several arrays (each "
|
|
923
1100
|
"keeps its values in storage of its own); convert them first "
|
|
924
|
-
"(
|
|
925
|
-
|
|
926
|
-
|
|
1101
|
+
"(%s)",
|
|
1102
|
+
who, rb_class2name(face_class),
|
|
1103
|
+
ca_face_conversion_hint(face));
|
|
927
1104
|
}
|
|
928
1105
|
for ( i = 1; i < n; i++ ) {
|
|
929
1106
|
VALUE p = rb_ary_entry(list, i);
|
|
@@ -956,7 +1133,7 @@ rb_ca_s_face_state_portable_p (VALUE klass)
|
|
|
956
1133
|
return Qtrue;
|
|
957
1134
|
}
|
|
958
1135
|
|
|
959
|
-
/* ca.
|
|
1136
|
+
/* ca.orderable_storage? -- whether ca's storage holds its values, in
|
|
960
1137
|
their order, so that a lookup may compare the storage: true for an array
|
|
961
1138
|
that is not a Face and for a Face that declares
|
|
962
1139
|
CA_FLAG_FACE_ORDERABLE_STORAGE, false for a Face whose cells encode the
|
|
@@ -970,7 +1147,7 @@ rb_ca_orderable_storage_p (VALUE self)
|
|
|
970
1147
|
return ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ? Qtrue : Qfalse;
|
|
971
1148
|
}
|
|
972
1149
|
|
|
973
|
-
/* ca.
|
|
1150
|
+
/* ca.comparable_storage? -- whether ca's storage holds its values as
|
|
974
1151
|
they are, so that a plain operand may be compared with the storage: true
|
|
975
1152
|
for an array that is not a Face and for a Face that declares
|
|
976
1153
|
CA_FLAG_FACE_COMPARABLE_STORAGE. */
|
|
@@ -983,7 +1160,7 @@ rb_ca_comparable_storage_p (VALUE self)
|
|
|
983
1160
|
return ca_test_flag(ca, CA_FLAG_FACE_COMPARABLE_STORAGE) ? Qtrue : Qfalse;
|
|
984
1161
|
}
|
|
985
1162
|
|
|
986
|
-
/* ca.
|
|
1163
|
+
/* ca.face_storage -- the storage under a Face (ca itself when it is not
|
|
987
1164
|
a Face). */
|
|
988
1165
|
static VALUE
|
|
989
1166
|
rb_ca_face_storage (VALUE self)
|
|
@@ -991,7 +1168,7 @@ rb_ca_face_storage (VALUE self)
|
|
|
991
1168
|
return rb_ca_strip_face_value(self);
|
|
992
1169
|
}
|
|
993
1170
|
|
|
994
|
-
/* ca.
|
|
1171
|
+
/* ca.reconcile_operand(operand, name) -- operand brought into ca's
|
|
995
1172
|
storage space by the rule every operand family follows
|
|
996
1173
|
(ca_face_reconcile_operand for a Face, ca_face_operand_descend for an
|
|
997
1174
|
array that is not one). For the families written in Ruby. */
|
|
@@ -1065,21 +1242,23 @@ ca_face_reconcile_comparison (volatile VALUE *pself, volatile VALUE *pother)
|
|
|
1065
1242
|
return;
|
|
1066
1243
|
}
|
|
1067
1244
|
|
|
1068
|
-
|
|
1069
|
-
ca_face_refuse_order("comparison", self, "compare");
|
|
1070
|
-
}
|
|
1245
|
+
ca_face_require_orderable(self, "comparison", "compare");
|
|
1071
1246
|
|
|
1072
1247
|
{
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1248
|
+
/* A Ruby Array is a list of values (to_comparable reads it cell by
|
|
1249
|
+
cell), not one value, so it keeps the length it was given. */
|
|
1250
|
+
int other_was_scalar = ! RTEST(rb_obj_is_carray(other))
|
|
1251
|
+
&& ! RB_TYPE_P(other, T_ARRAY);
|
|
1252
|
+
volatile VALUE ref = self, op = other;
|
|
1253
|
+
ca_face_reconcile_pair(&ref, &op, "comparison");
|
|
1254
|
+
/* The reconcile lifts a scalar operand to a length-1 array; unwrap it
|
|
1076
1255
|
so the comparison stays array-vs-scalar instead of a shape check
|
|
1077
1256
|
against [1] (which only a 1-D reference would pass). */
|
|
1078
|
-
if ( other_was_scalar && RTEST(rb_obj_is_carray(
|
|
1079
|
-
|
|
1257
|
+
if ( other_was_scalar && RTEST(rb_obj_is_carray(op)) ) {
|
|
1258
|
+
op = rb_ca_fetch_addr(op, 0);
|
|
1080
1259
|
}
|
|
1081
|
-
*pself = rb_ca_strip_face_value(
|
|
1082
|
-
*pother =
|
|
1260
|
+
*pself = rb_ca_strip_face_value(ref);
|
|
1261
|
+
*pother = op;
|
|
1083
1262
|
}
|
|
1084
1263
|
}
|
|
1085
1264
|
|
|
@@ -1105,12 +1284,14 @@ Init_ca_face (void)
|
|
|
1105
1284
|
rb_define_singleton_method(rb_cCArray, "face_state_portable?",
|
|
1106
1285
|
rb_ca_s_face_state_portable_p, 0);
|
|
1107
1286
|
rb_define_method(rb_cCArray, "face_lift", rb_ca_face_lift_method, 1);
|
|
1108
|
-
rb_define_private_method(rb_cCArray, "
|
|
1287
|
+
rb_define_private_method(rb_cCArray, "orderable_storage?",
|
|
1109
1288
|
rb_ca_orderable_storage_p, 0);
|
|
1110
|
-
rb_define_private_method(rb_cCArray, "
|
|
1289
|
+
rb_define_private_method(rb_cCArray, "comparable_storage?",
|
|
1111
1290
|
rb_ca_comparable_storage_p, 0);
|
|
1112
|
-
rb_define_private_method(rb_cCArray, "
|
|
1291
|
+
rb_define_private_method(rb_cCArray, "face_storage",
|
|
1113
1292
|
rb_ca_face_storage, 0);
|
|
1114
|
-
rb_define_private_method(rb_cCArray, "
|
|
1293
|
+
rb_define_private_method(rb_cCArray, "reconcile_operand",
|
|
1115
1294
|
rb_ca_reconcile_operand, 2);
|
|
1295
|
+
rb_define_private_method(rb_cCArray, "face_storage_method",
|
|
1296
|
+
rb_ca_face_storage_method, 0);
|
|
1116
1297
|
}
|
data/ext/ca_obj_face.h
CHANGED
|
@@ -104,6 +104,10 @@ void Init_ca_face (void);
|
|
|
104
104
|
extern int8_t CA_OBJ_RECORD;
|
|
105
105
|
VALUE rb_ca_record_get_data_class (CArray *ca);
|
|
106
106
|
|
|
107
|
+
/* CA_OBJ_STRING identifies CAString, read by the store path
|
|
108
|
+
(carray_access.c) to send an array source through the write hook. */
|
|
109
|
+
extern int8_t CA_OBJ_STRING;
|
|
110
|
+
|
|
107
111
|
/* -- Convenience macro for view-creating method deployment --
|
|
108
112
|
Insert at the tail of each view-creating Ruby method (= rb_ca_transpose
|
|
109
113
|
/ rb_ca_reshape / etc.) just before return. `ca` is self's CArray *,
|
|
@@ -288,10 +292,25 @@ VALUE ca_face_strip_one (VALUE v);
|
|
|
288
292
|
NORETURN(void ca_face_refuse_order (const char *name, VALUE face,
|
|
289
293
|
const char *verb));
|
|
290
294
|
|
|
295
|
+
/* The gate of every family that orders, compares, searches or hashes a Face
|
|
296
|
+
reference: returns when the Face is ORDERABLE_STORAGE, refuses otherwise
|
|
297
|
+
(ca_face_refuse_order). Call this rather than testing the flag. */
|
|
298
|
+
void ca_face_require_orderable (VALUE face, const char *name,
|
|
299
|
+
const char *verb);
|
|
300
|
+
|
|
301
|
+
/* Whether a Face is not ORDERABLE and answers #order itself (CAConstString,
|
|
302
|
+
CARecord), so a family that orders by a key takes that order instead of
|
|
303
|
+
the storage. */
|
|
304
|
+
int ca_face_orders_by_itself (VALUE face);
|
|
305
|
+
|
|
291
306
|
/* The conversion a refusal of a Face whose cells encode its values points
|
|
292
307
|
at (#to_string for a string Face, to_type(:object) for any other). */
|
|
293
308
|
const char *ca_face_conversion_hint (VALUE face);
|
|
294
309
|
|
|
310
|
+
/* The method that gives the storage under a Face (#ticks, #codes), or NULL
|
|
311
|
+
when the Face has none of those. */
|
|
312
|
+
const char *ca_face_storage_method (VALUE face);
|
|
313
|
+
|
|
295
314
|
/* Raise eclass naming a Face that does not define the numeric operation
|
|
296
315
|
`name`; returns when self is not a Face. See ca_obj_face.c. */
|
|
297
316
|
void ca_face_refuse_numeric (VALUE self, const char *name, VALUE eclass);
|
data/ext/ca_obj_fake.c
CHANGED
|
@@ -78,8 +78,14 @@ ca_fake_setup (CAFake *ca, CArray *parent, int8_t data_type, ca_size_t bytes)
|
|
|
78
78
|
|
|
79
79
|
/* check arguments */
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
CA_CHECK_DATA_TYPE_GIVEN(data_type);
|
|
82
|
+
CA_CHECK_BYTES_GIVEN(data_type, bytes);
|
|
83
|
+
|
|
84
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
85
|
+
run them before it allocates. */
|
|
86
|
+
if ( ca == NULL ) {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
83
89
|
|
|
84
90
|
ndim = parent->ndim;
|
|
85
91
|
dim = parent->dim;
|
|
@@ -103,9 +109,6 @@ ca_fake_setup (CAFake *ca, CArray *parent, int8_t data_type, ca_size_t bytes)
|
|
|
103
109
|
|
|
104
110
|
memcpy(ca->dim, dim, ndim * sizeof(ca_size_t));
|
|
105
111
|
|
|
106
|
-
if ( ca_has_mask(parent) ) {
|
|
107
|
-
ca_create_mask(ca);
|
|
108
|
-
}
|
|
109
112
|
|
|
110
113
|
if ( ca_is_scalar(parent) ) {
|
|
111
114
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
@@ -117,8 +120,11 @@ ca_fake_setup (CAFake *ca, CArray *parent, int8_t data_type, ca_size_t bytes)
|
|
|
117
120
|
CAFake *
|
|
118
121
|
ca_fake_new (CArray *parent, int8_t data_type, ca_size_t bytes)
|
|
119
122
|
{
|
|
120
|
-
CAFake *ca
|
|
123
|
+
CAFake *ca;
|
|
124
|
+
ca_fake_setup(NULL, parent, data_type, bytes);
|
|
125
|
+
ca = (CAFake *) ca_array_alloc(CA_OBJ_FAKE, parent->ndim);
|
|
121
126
|
ca_fake_setup(ca, parent, data_type, bytes);
|
|
127
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
122
128
|
return ca;
|
|
123
129
|
}
|
|
124
130
|
|
|
@@ -277,18 +283,7 @@ ca_fake_func_allocate (void *ap)
|
|
|
277
283
|
{
|
|
278
284
|
CAFake *ca = (CAFake *) ap;
|
|
279
285
|
ca_attach(ca->parent);
|
|
280
|
-
ca->ptr =
|
|
281
|
-
|
|
282
|
-
/* CAREFUL: CA_OBJECT storage must contain valid VALUEs before GC can
|
|
283
|
-
scan it, so seed with Fixnum 0 rather than leaving raw xmalloc bytes. */
|
|
284
|
-
if ( ca->data_type == CA_OBJECT ) {
|
|
285
|
-
VALUE *p = (VALUE *) ca->ptr;
|
|
286
|
-
VALUE zero = SIZE2NUM(0);
|
|
287
|
-
ca_size_t i;
|
|
288
|
-
for (i=0; i<ca->elements; i++) {
|
|
289
|
-
*p++ = zero;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
286
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
292
287
|
}
|
|
293
288
|
|
|
294
289
|
static void
|
|
@@ -296,17 +291,7 @@ ca_fake_func_attach (void *ap)
|
|
|
296
291
|
{
|
|
297
292
|
CAFake *ca = (CAFake *) ap;
|
|
298
293
|
ca_attach(ca->parent);
|
|
299
|
-
ca->ptr =
|
|
300
|
-
|
|
301
|
-
/* CAREFUL: same VALUE-seed rule as ca_fake_func_allocate. */
|
|
302
|
-
if ( ca->data_type == CA_OBJECT ) {
|
|
303
|
-
VALUE *p = (VALUE *) ca->ptr;
|
|
304
|
-
VALUE zero = SIZE2NUM(0);
|
|
305
|
-
ca_size_t i;
|
|
306
|
-
for (i=0; i<ca->elements; i++) {
|
|
307
|
-
*p++ = zero;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
294
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
310
295
|
|
|
311
296
|
if ( ca->parent->mask ) {
|
|
312
297
|
ca_cast_block_with_mask(ca->elements, ca->parent, ca->parent->ptr,
|
|
@@ -499,6 +484,7 @@ rb_ca_fake_initialize_copy (VALUE self, VALUE other)
|
|
|
499
484
|
ca_array_pool_alloc(ca, CA_OBJ_FAKE, cs->parent->ndim);
|
|
500
485
|
}
|
|
501
486
|
ca_fake_setup(ca, cs->parent, cs->data_type, cs->bytes);
|
|
487
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
502
488
|
|
|
503
489
|
return self;
|
|
504
490
|
}
|
data/ext/ca_obj_farray.c
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
---------------------------------------------------------------------------- */
|
|
8
8
|
|
|
9
9
|
#include "carray.h"
|
|
10
|
+
#include "carray_internal.h" /* ca_view_inherit_mask */
|
|
10
11
|
|
|
11
12
|
extern ca_operation_function_t ca_stride_func;
|
|
12
13
|
|
|
@@ -46,9 +47,9 @@ ca_farray_setup (CAStride *ca, CArray *parent)
|
|
|
46
47
|
strides[i] = parent_byte_stride[ndim - 1 - i];
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
ca_stride_setup_view(ca, CA_OBJ_FARRAY, parent,
|
|
51
|
+
parent->data_type, parent->bytes,
|
|
52
|
+
ndim, newdim, strides, 0);
|
|
52
53
|
|
|
53
54
|
if (ca_is_scalar(parent)) {
|
|
54
55
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
@@ -59,8 +60,10 @@ ca_farray_setup (CAStride *ca, CArray *parent)
|
|
|
59
60
|
CAStride *
|
|
60
61
|
ca_farray_new (CArray *parent)
|
|
61
62
|
{
|
|
63
|
+
/* check: the parent's shape, reversed, is already valid */
|
|
62
64
|
CAStride *ca = (CAStride *) ca_array_alloc(CA_OBJ_FARRAY, parent->ndim);
|
|
63
65
|
ca_farray_setup(ca, parent);
|
|
66
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
64
67
|
return ca;
|
|
65
68
|
}
|
|
66
69
|
|