carray 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +824 -0
- data/README.md +5 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +258 -4
- data/ext/ca_axis_group.c +368 -184
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +90 -41
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +960 -245
- data/ext/ca_kernel_iterator.h +352 -181
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +194 -42
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +5 -4
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +180 -50
- data/ext/ca_obj_face.c +428 -62
- data/ext/ca_obj_face.h +107 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +39 -26
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +235 -55
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +551 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +88 -75
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -123
- data/ext/ca_obj_stride.c +267 -35
- data/ext/ca_obj_string.c +25 -22
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +157 -29
- data/ext/ca_op_ipower.c +25 -13
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +385 -198
- data/ext/ca_sweep_engine.h +31 -23
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +90 -28
- data/ext/carray_access.c +487 -231
- data/ext/carray_address_basis.c +731 -0
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +49 -17
- data/ext/carray_call_cfunc.c +667 -511
- data/ext/carray_cast.c +1556 -247
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +84 -38
- data/ext/carray_core.c +591 -119
- data/ext/carray_count.c +148 -96
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +604 -291
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +400 -1
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +88 -66
- data/ext/carray_mask.c +705 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +263 -63
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1093 -363
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +582 -204
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +183 -70
- data/ext/carray_sort.c +235 -240
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +103 -118
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1349 -851
- data/ext/ruby_carray.c +17 -2
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +18 -0
- data/lib/carray/axis_group.rb +245 -20
- data/lib/carray/basics.rb +95 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +200 -54
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +244 -59
- data/lib/carray/categorical_iterator.rb +391 -757
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +177 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +590 -76
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +205 -35
- data/lib/carray/frame/group.rb +199 -40
- data/lib/carray/frame/io.rb +452 -60
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +54 -19
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +726 -56
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +71 -20
- data/lib/carray/iterator.rb +157 -2
- data/lib/carray/lazy.rb +54 -67
- data/lib/carray/mask_gap_fill.rb +66 -50
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +130 -6
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +235 -21
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +91 -0
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +52 -3
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +109 -40
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +9 -4
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +535 -105
- data/lib/carray/window_iterator.rb +259 -82
- data/lib/carray.rb +4 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_block.rb +2 -7
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +11 -4
- data/yard-stubs/carray_access.rb +6 -5
- data/yard-stubs/carray_broadcast.rb +2 -2
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -83
- data/yard-stubs/carray_count.rb +16 -2
- data/yard-stubs/carray_lazy.rb +210 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +1499 -4
- data/yard-stubs/carray_median_percentile.rb +26 -8
- data/yard-stubs/carray_order.rb +43 -82
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +11 -8
- data/yard-stubs/carray_sort.rb +50 -8
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -25837
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14593
- data/ext/carray_kernels_reduce_extreme.c +0 -16948
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32138
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/ca_obj_face.c
CHANGED
|
@@ -19,16 +19,18 @@
|
|
|
19
19
|
ca_face_lift re-wrap a view as a Face when the source was
|
|
20
20
|
ca_strip_face walk down through Face parents to storage
|
|
21
21
|
CAFace abstract class organisational relay in the class hierarchy
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
storage_to_element / per-obj_type dispatch for element decode (read)
|
|
23
|
+
element_to_storage and encode (write) between surface and storage
|
|
24
24
|
state-compatible / homogeneity + portability registries used by
|
|
25
|
-
state-portable promote_list / CAStack
|
|
25
|
+
state-portable promote_list / CAStack
|
|
26
|
+
memory_view which Faces the MemoryView producer exports
|
|
26
27
|
|
|
27
28
|
---------------------------------------------------------------------------- */
|
|
28
29
|
|
|
29
30
|
#include "ruby.h"
|
|
30
31
|
#include "carray.h"
|
|
31
32
|
#include "ca_obj_face.h"
|
|
33
|
+
#include "carray_internal.h"
|
|
32
34
|
|
|
33
35
|
/* ---- shared op helpers (thin-forward) ---- */
|
|
34
36
|
|
|
@@ -37,7 +39,7 @@ ca_face_attach (void *ap)
|
|
|
37
39
|
{
|
|
38
40
|
CAView *cav = (CAView *) ap;
|
|
39
41
|
CArray *ca = (CArray *) ap;
|
|
40
|
-
ca_attach(cav->parent);
|
|
42
|
+
ca_attach(cav->parent); /* window: a Face's attach slot; its detach slot releases */
|
|
41
43
|
/* alias parent->ptr (Face has identical data layout, so copy is unneeded) */
|
|
42
44
|
ca->ptr = cav->parent->ptr;
|
|
43
45
|
}
|
|
@@ -100,6 +102,7 @@ void
|
|
|
100
102
|
ca_face_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
101
103
|
ca_size_t *strides, void *data, int dir)
|
|
102
104
|
{
|
|
105
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
103
106
|
CAView *cav = (CAView *) ap;
|
|
104
107
|
ca_xfer_stride(cav->parent, starts, counts, strides, data, dir);
|
|
105
108
|
}
|
|
@@ -174,6 +177,27 @@ rb_ca_face_template (VALUE original_face, CArray *new_parent,
|
|
|
174
177
|
dst);
|
|
175
178
|
}
|
|
176
179
|
|
|
180
|
+
VALUE
|
|
181
|
+
ca_face_relift_entity (VALUE face, VALUE result)
|
|
182
|
+
{
|
|
183
|
+
static ID id_copy_state = 0;
|
|
184
|
+
CArray *rc, *lc;
|
|
185
|
+
VALUE lifted;
|
|
186
|
+
if ( id_copy_state == 0 ) id_copy_state = rb_intern("copy_state");
|
|
187
|
+
TypedData_Get_Struct(result, CArray, &carray_data_type, rc);
|
|
188
|
+
lifted = rb_ca_face_template(face, rc, rc->dim);
|
|
189
|
+
rb_ca_set_parent(lifted, result);
|
|
190
|
+
if ( ca_has_mask(rc) ) {
|
|
191
|
+
/* The template starts without a mask. */
|
|
192
|
+
TypedData_Get_Struct(lifted, CArray, &carray_data_type, lc);
|
|
193
|
+
ca_copy_mask(lc, rc);
|
|
194
|
+
}
|
|
195
|
+
if ( rb_respond_to(face, id_copy_state) ) {
|
|
196
|
+
rb_funcall(lifted, id_copy_state, 1, face);
|
|
197
|
+
}
|
|
198
|
+
return lifted;
|
|
199
|
+
}
|
|
200
|
+
|
|
177
201
|
/* ca_face_lift(view, face_parent) — at the tail of user-facing entry
|
|
178
202
|
* points (`ca[...]` etc.), when the operand was a Face, re-wrap the
|
|
179
203
|
* resulting view as a Face of the same subclass. Thin wrapper over
|
|
@@ -419,37 +443,62 @@ rb_ca_face_s_allocate_forbidden (VALUE klass)
|
|
|
419
443
|
"(CATime / CATimedelta / ...)");
|
|
420
444
|
}
|
|
421
445
|
|
|
422
|
-
|
|
446
|
+
VALUE
|
|
447
|
+
ca_face_storage_value (CArray *ca, VALUE raw)
|
|
448
|
+
{
|
|
449
|
+
CArray *storage;
|
|
450
|
+
CArray as_storage;
|
|
451
|
+
if ( ca->data_type != CA_FIXLEN || TYPE(raw) != T_STRING ) {
|
|
452
|
+
return raw;
|
|
453
|
+
}
|
|
454
|
+
storage = ca_strip_face(ca);
|
|
455
|
+
if ( storage == NULL
|
|
456
|
+
|| storage->data_type == CA_FIXLEN
|
|
457
|
+
|| ca_is_object_type(storage)
|
|
458
|
+
|| RSTRING_LEN(raw) != storage->bytes ) {
|
|
459
|
+
return raw;
|
|
460
|
+
}
|
|
461
|
+
if ( storage->data_type == CA_BOOLEAN ) {
|
|
462
|
+
return *(uint8_t *) RSTRING_PTR(raw) ? Qtrue : Qfalse;
|
|
463
|
+
}
|
|
464
|
+
/* The cell lives in a String's buffer, not in the storage: read it
|
|
465
|
+
through a stand-in that carries only the storage's type. */
|
|
466
|
+
as_storage.data_type = storage->data_type;
|
|
467
|
+
as_storage.bytes = storage->bytes;
|
|
468
|
+
return ca_ptr2obj(&as_storage, RSTRING_PTR(raw));
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* Face-local C dispatch table for storage_to_element (the read/decode
|
|
423
472
|
direction). Sized to CA_OBJ_TYPE_MAX so any registered obj_type can be
|
|
424
473
|
indexed directly; file-scope zero-init leaves unregistered slots NULL. */
|
|
425
|
-
|
|
474
|
+
ca_face_storage_to_element_fn ca_face_storage_to_element_table[CA_OBJ_TYPE_MAX];
|
|
426
475
|
|
|
427
476
|
void
|
|
428
|
-
|
|
477
|
+
ca_face_register_storage_to_element (int obj_type, ca_face_storage_to_element_fn fn)
|
|
429
478
|
{
|
|
430
479
|
if ( obj_type < 0 || obj_type >= CA_OBJ_TYPE_MAX ) {
|
|
431
480
|
rb_raise(rb_eArgError,
|
|
432
|
-
"
|
|
481
|
+
"ca_face_register_storage_to_element: obj_type %d out of range",
|
|
433
482
|
obj_type);
|
|
434
483
|
}
|
|
435
|
-
|
|
484
|
+
ca_face_storage_to_element_table[obj_type] = fn;
|
|
436
485
|
}
|
|
437
486
|
|
|
438
|
-
/* Face-local C dispatch table for
|
|
487
|
+
/* Face-local C dispatch table for element_to_storage (the write/encode
|
|
439
488
|
direction), the mirror of the decode table above. Unregistered slots
|
|
440
489
|
stay NULL; a Face without a C fast path relies on the Ruby fallback in
|
|
441
|
-
|
|
442
|
-
|
|
490
|
+
ca_face_element_to_storage (carray_cast.c). */
|
|
491
|
+
ca_face_element_to_storage_fn ca_face_element_to_storage_table[CA_OBJ_TYPE_MAX];
|
|
443
492
|
|
|
444
493
|
void
|
|
445
|
-
|
|
494
|
+
ca_face_register_element_to_storage (int obj_type, ca_face_element_to_storage_fn fn)
|
|
446
495
|
{
|
|
447
496
|
if ( obj_type < 0 || obj_type >= CA_OBJ_TYPE_MAX ) {
|
|
448
497
|
rb_raise(rb_eArgError,
|
|
449
|
-
"
|
|
498
|
+
"ca_face_register_element_to_storage: obj_type %d out of range",
|
|
450
499
|
obj_type);
|
|
451
500
|
}
|
|
452
|
-
|
|
501
|
+
ca_face_element_to_storage_table[obj_type] = fn;
|
|
453
502
|
}
|
|
454
503
|
|
|
455
504
|
/* -- Face state homogeneity check -- */
|
|
@@ -524,6 +573,31 @@ rb_ca_face_state_compatible_p (VALUE self, VALUE other)
|
|
|
524
573
|
return ca_face_state_compatible(self, a, other, b) ? Qtrue : Qfalse;
|
|
525
574
|
}
|
|
526
575
|
|
|
576
|
+
/* -- Face MemoryView export -- */
|
|
577
|
+
|
|
578
|
+
/* A Face is exported through MemoryView only when its storage bytes carry
|
|
579
|
+
its values without the Face (a struct record, fixed-width bytes). Zero
|
|
580
|
+
(the default) refuses the export: the consumer would see the storage
|
|
581
|
+
with nothing to say what it means. */
|
|
582
|
+
static int8_t ca_face_memory_view_table[CA_OBJ_TYPE_MAX];
|
|
583
|
+
|
|
584
|
+
void
|
|
585
|
+
ca_face_register_memory_view (int obj_type, int exportable)
|
|
586
|
+
{
|
|
587
|
+
if ( obj_type < 0 || obj_type >= CA_OBJ_TYPE_MAX ) {
|
|
588
|
+
rb_raise(rb_eArgError,
|
|
589
|
+
"ca_face_register_memory_view: obj_type %d out of range",
|
|
590
|
+
obj_type);
|
|
591
|
+
}
|
|
592
|
+
ca_face_memory_view_table[obj_type] = exportable ? 1 : 0;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
int
|
|
596
|
+
ca_face_memory_view_exportable (CArray *ca)
|
|
597
|
+
{
|
|
598
|
+
return ca_face_memory_view_table[ca->obj_type] == 1;
|
|
599
|
+
}
|
|
600
|
+
|
|
527
601
|
/* -- Face state portability -- */
|
|
528
602
|
|
|
529
603
|
/* int8_t per slot to distinguish "unregistered" (-1, dispatch falls
|
|
@@ -595,6 +669,207 @@ ca_face_class_has_portable_method (VALUE klass)
|
|
|
595
669
|
return ( owner != rb_singleton_class(rb_cCArray) ) ? 1 : 0;
|
|
596
670
|
}
|
|
597
671
|
|
|
672
|
+
/* The conversion a refusal of a Face whose cells encode its values points
|
|
673
|
+
at: a string Face gives its strings with #to_string, any other its values
|
|
674
|
+
with to_type(:object). */
|
|
675
|
+
const char *
|
|
676
|
+
ca_face_conversion_hint (VALUE face)
|
|
677
|
+
{
|
|
678
|
+
return rb_respond_to(face, rb_intern("to_string"))
|
|
679
|
+
? "#to_string gives its strings"
|
|
680
|
+
: "to_type(:object) gives its values";
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/* Refuse to order (or, with verb "count", to count by value) a Face whose
|
|
684
|
+
storage does not hold its values in order, pointing at what does: its
|
|
685
|
+
values, or its storage when that is what is meant. */
|
|
686
|
+
void
|
|
687
|
+
ca_face_refuse_order (const char *name, VALUE face, const char *verb)
|
|
688
|
+
{
|
|
689
|
+
rb_raise(rb_eArgError,
|
|
690
|
+
"%s: %s is not orderable by storage (a cell encodes the value "
|
|
691
|
+
"rather than being it); %s its values instead -- %s -- or pass "
|
|
692
|
+
".parent to %s its storage",
|
|
693
|
+
name, rb_obj_classname(face), verb,
|
|
694
|
+
ca_face_conversion_hint(face), verb);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/* Refuse a numeric operation (arithmetic, math, a reduction) on a Face,
|
|
698
|
+
whose cells encode its values rather than being numbers, pointing at what
|
|
699
|
+
gives numbers. Returns when `self` is not a Face. */
|
|
700
|
+
void
|
|
701
|
+
ca_face_refuse_numeric (VALUE self, const char *name, VALUE eclass)
|
|
702
|
+
{
|
|
703
|
+
CArray *ca;
|
|
704
|
+
if ( ! rb_obj_is_carray(self) ) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
GetCArray(self, ca);
|
|
708
|
+
if ( ! ca_is_face(ca) ) {
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
rb_raise(eclass,
|
|
712
|
+
"%s: %s does not define it (a cell encodes the value rather than "
|
|
713
|
+
"being a number); compute on its values instead -- %s -- or pass "
|
|
714
|
+
".parent to compute on its storage",
|
|
715
|
+
name, rb_obj_classname(self), ca_face_conversion_hint(self));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
VALUE
|
|
719
|
+
ca_face_operand_descend (VALUE operand, const char *name)
|
|
720
|
+
{
|
|
721
|
+
CArray *op;
|
|
722
|
+
if ( ! RTEST(rb_obj_is_carray(operand)) ) {
|
|
723
|
+
return operand;
|
|
724
|
+
}
|
|
725
|
+
TypedData_Get_Struct(operand, CArray, &carray_data_type, op);
|
|
726
|
+
if ( ! ca_is_face(op) ) {
|
|
727
|
+
return operand;
|
|
728
|
+
}
|
|
729
|
+
if ( ca_test_flag(op, CA_FLAG_FACE_COMPARABLE_STORAGE) ) {
|
|
730
|
+
return rb_ca_strip_face_value(operand);
|
|
731
|
+
}
|
|
732
|
+
rb_raise(rb_eArgError,
|
|
733
|
+
"%s: cannot take a %s operand: its storage is not its surface "
|
|
734
|
+
"(a cell encodes the value rather than being it), so comparing "
|
|
735
|
+
"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",
|
|
738
|
+
name, rb_obj_classname(operand), ca_face_conversion_hint(operand));
|
|
739
|
+
return Qnil; /* not reached */
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/* Whether two arrays, at least one a Face other than a record array, are
|
|
743
|
+
equal (`==`, strict = 0) or the same key (`eql?`, strict = 1).
|
|
744
|
+
|
|
745
|
+
A Face equals only a Face of its own class. When the two share their
|
|
746
|
+
state (a time array's unit) and the storage holds the values in their
|
|
747
|
+
order, equal storage is equal values, so the storage is compared.
|
|
748
|
+
Otherwise `==` compares the values themselves (two time arrays of
|
|
749
|
+
different units, two const strings over different pools, two
|
|
750
|
+
categoricals with differently ordered labels), and `eql?`, which has to
|
|
751
|
+
agree with #hash, answers false. */
|
|
752
|
+
int
|
|
753
|
+
ca_face_equal (VALUE va, VALUE vb, int strict)
|
|
754
|
+
{
|
|
755
|
+
CArray *a, *b;
|
|
756
|
+
int8_t i;
|
|
757
|
+
TypedData_Get_Struct(va, CArray, &carray_data_type, a);
|
|
758
|
+
TypedData_Get_Struct(vb, CArray, &carray_data_type, b);
|
|
759
|
+
if ( ! ca_is_face(a) || ! ca_is_face(b) ) {
|
|
760
|
+
return 0;
|
|
761
|
+
}
|
|
762
|
+
if ( rb_obj_class(va) != rb_obj_class(vb) ) {
|
|
763
|
+
return 0;
|
|
764
|
+
}
|
|
765
|
+
if ( a->ndim != b->ndim ) {
|
|
766
|
+
return 0;
|
|
767
|
+
}
|
|
768
|
+
for (i = 0; i < a->ndim; i++) {
|
|
769
|
+
if ( a->dim[i] != b->dim[i] ) {
|
|
770
|
+
return 0;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
if ( ca_face_state_compatible(va, a, vb, b)
|
|
774
|
+
&& ( strict || ca_test_flag(a, CA_FLAG_FACE_ORDERABLE_STORAGE) ) ) {
|
|
775
|
+
return strict ? ca_eql_storage(ca_strip_face(a), ca_strip_face(b))
|
|
776
|
+
: ca_equal(ca_strip_face(a), ca_strip_face(b));
|
|
777
|
+
}
|
|
778
|
+
if ( strict ) {
|
|
779
|
+
return 0;
|
|
780
|
+
}
|
|
781
|
+
return RTEST(rb_equal(rb_funcall(va, rb_intern("to_a"), 0),
|
|
782
|
+
rb_funcall(vb, rb_intern("to_a"), 0)));
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/* An operand Face whose storage is not even in the order of its values
|
|
786
|
+
(a CAConstString, a CACategorical) is read by its values: its strings
|
|
787
|
+
(#to_string) or, for any other, its values (to_type(:object)). Any
|
|
788
|
+
other operand is returned as it is. */
|
|
789
|
+
static VALUE
|
|
790
|
+
ca_face_operand_values (VALUE operand)
|
|
791
|
+
{
|
|
792
|
+
CArray *op;
|
|
793
|
+
if ( ! RTEST(rb_obj_is_carray(operand)) ) {
|
|
794
|
+
return operand;
|
|
795
|
+
}
|
|
796
|
+
TypedData_Get_Struct(operand, CArray, &carray_data_type, op);
|
|
797
|
+
if ( ! ca_is_face(op) || op->obj_type == CA_OBJ_RECORD
|
|
798
|
+
|| ca_test_flag(op, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
799
|
+
return operand;
|
|
800
|
+
}
|
|
801
|
+
if ( rb_respond_to(operand, rb_intern("to_string")) ) {
|
|
802
|
+
return rb_funcall(operand, rb_intern("to_string"), 0);
|
|
803
|
+
}
|
|
804
|
+
return rb_funcall(operand, rb_intern("to_type"), 1, INT2NUM(CA_OBJECT));
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/* Bring `operand` into the storage space of `reference`, a Face, so the
|
|
808
|
+
two can be compared, searched, counted or hashed cell by cell. Every
|
|
809
|
+
family that takes an operand against a Face goes through here; the
|
|
810
|
+
family keeps its own gate on the reference (ORDERABLE, a record's own
|
|
811
|
+
rules) and its own handling of a scalar operand afterwards.
|
|
812
|
+
|
|
813
|
+
- A record reference takes records of its own data_class (stripped to
|
|
814
|
+
their bytes) and plain operands as they are; any other Face operand is
|
|
815
|
+
refused with TypeError.
|
|
816
|
+
- A COMPARABLE reference stores its values as they are, so a plain
|
|
817
|
+
operand is taken as it is, a Face whose cells are its values is
|
|
818
|
+
stripped, a string or categorical Face is read by its values, and a
|
|
819
|
+
Face whose cells encode its values in order (a time) is refused
|
|
820
|
+
(ca_face_operand_descend).
|
|
821
|
+
- A reference whose storage is not in the order of its values refuses,
|
|
822
|
+
naming the conversion that gives its values.
|
|
823
|
+
- A reference with to_comparable brings any operand into its own space
|
|
824
|
+
(a unit, an instant), and refuses what it cannot convert.
|
|
825
|
+
- Any other reference has no way to read the operand in its space, and
|
|
826
|
+
refuses it. */
|
|
827
|
+
VALUE
|
|
828
|
+
ca_face_reconcile_operand (VALUE reference, VALUE operand, const char *name)
|
|
829
|
+
{
|
|
830
|
+
CArray *ca;
|
|
831
|
+
TypedData_Get_Struct(reference, CArray, &carray_data_type, ca);
|
|
832
|
+
if ( ca->obj_type == CA_OBJ_RECORD ) {
|
|
833
|
+
if ( RTEST(rb_obj_is_carray(operand)) ) {
|
|
834
|
+
CArray *op;
|
|
835
|
+
TypedData_Get_Struct(operand, CArray, &carray_data_type, op);
|
|
836
|
+
if ( ca_is_face(op) ) {
|
|
837
|
+
if ( op->obj_type != CA_OBJ_RECORD ) {
|
|
838
|
+
rb_raise(rb_eTypeError,
|
|
839
|
+
"%s: can not take a %s operand for a record array of "
|
|
840
|
+
"%"PRIsVALUE, name, rb_obj_classname(operand),
|
|
841
|
+
rb_ca_data_class(reference));
|
|
842
|
+
}
|
|
843
|
+
if ( rb_ca_data_class(operand) != rb_ca_data_class(reference) ) {
|
|
844
|
+
rb_raise(rb_eTypeError,
|
|
845
|
+
"%s: can not take a record array of %"PRIsVALUE
|
|
846
|
+
" for a record array of %"PRIsVALUE, name,
|
|
847
|
+
rb_ca_data_class(operand), rb_ca_data_class(reference));
|
|
848
|
+
}
|
|
849
|
+
return rb_ca_strip_face_value(operand);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return operand;
|
|
853
|
+
}
|
|
854
|
+
if ( ca_test_flag(ca, CA_FLAG_FACE_COMPARABLE_STORAGE) ) {
|
|
855
|
+
return ca_face_operand_descend(ca_face_operand_values(operand), name);
|
|
856
|
+
}
|
|
857
|
+
if ( ! ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
858
|
+
ca_face_refuse_order(name, reference, "compare");
|
|
859
|
+
}
|
|
860
|
+
if ( rb_respond_to(reference, rb_intern("to_comparable")) ) {
|
|
861
|
+
return rb_ca_strip_face_value(rb_funcall(reference,
|
|
862
|
+
rb_intern("to_comparable"),
|
|
863
|
+
1, operand));
|
|
864
|
+
}
|
|
865
|
+
rb_raise(rb_eArgError,
|
|
866
|
+
"%s: %s is not comparable by storage and has no to_comparable "
|
|
867
|
+
"to bring the operand into its space; pass .parent on both "
|
|
868
|
+
"sides to work in storage space",
|
|
869
|
+
name, rb_obj_classname(reference));
|
|
870
|
+
return Qnil; /* not reached */
|
|
871
|
+
}
|
|
872
|
+
|
|
598
873
|
int
|
|
599
874
|
ca_face_state_portable (int obj_type, VALUE klass)
|
|
600
875
|
{
|
|
@@ -611,6 +886,66 @@ ca_face_state_portable (int obj_type, VALUE klass)
|
|
|
611
886
|
return 1; /* default portable */
|
|
612
887
|
}
|
|
613
888
|
|
|
889
|
+
VALUE
|
|
890
|
+
ca_face_list_class (VALUE list, const char *who)
|
|
891
|
+
{
|
|
892
|
+
long n = RARRAY_LEN(list), i;
|
|
893
|
+
int any_face = 0, all_face = 1;
|
|
894
|
+
VALUE face_class = Qnil;
|
|
895
|
+
CArray *ref = NULL;
|
|
896
|
+
|
|
897
|
+
for ( i = 0; i < n; i++ ) {
|
|
898
|
+
VALUE p = rb_ary_entry(list, i);
|
|
899
|
+
CArray *ca;
|
|
900
|
+
rb_check_carray_object(p);
|
|
901
|
+
TypedData_Get_Struct(p, CArray, &carray_data_type, ca);
|
|
902
|
+
if ( ! ca_is_face(ca) ) { all_face = 0; continue; }
|
|
903
|
+
any_face = 1;
|
|
904
|
+
if ( NIL_P(face_class) ) {
|
|
905
|
+
face_class = rb_obj_class(p);
|
|
906
|
+
ref = ca;
|
|
907
|
+
}
|
|
908
|
+
else if ( rb_obj_class(p) != face_class ) {
|
|
909
|
+
all_face = 0;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if ( ! any_face ) return Qnil;
|
|
913
|
+
if ( ! all_face ) {
|
|
914
|
+
rb_raise(rb_eArgError,
|
|
915
|
+
"%s: cannot mix Face and non-Face arrays, or arrays of "
|
|
916
|
+
"different Face classes; convert them to one Face class, or "
|
|
917
|
+
"none, first, or take .parent of each to combine the storage",
|
|
918
|
+
who);
|
|
919
|
+
}
|
|
920
|
+
if ( n > 1 && ! ca_face_state_portable(ref->obj_type, face_class) ) {
|
|
921
|
+
rb_raise(rb_eArgError,
|
|
922
|
+
"%s: %s state is not portable across several arrays (each "
|
|
923
|
+
"keeps its values in storage of its own); convert them first "
|
|
924
|
+
"(a CAConstString with to_string), or take .parent of each to "
|
|
925
|
+
"combine the storage",
|
|
926
|
+
who, rb_class2name(face_class));
|
|
927
|
+
}
|
|
928
|
+
for ( i = 1; i < n; i++ ) {
|
|
929
|
+
VALUE p = rb_ary_entry(list, i);
|
|
930
|
+
CArray *ca;
|
|
931
|
+
TypedData_Get_Struct(p, CArray, &carray_data_type, ca);
|
|
932
|
+
if ( ! ca_face_state_compatible(rb_ary_entry(list, 0), ref, p, ca) ) {
|
|
933
|
+
rb_raise(rb_eArgError,
|
|
934
|
+
"%s: Face state mismatch (the %s at index %ld differs from "
|
|
935
|
+
"index 0)", who, rb_class2name(face_class), i);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
return face_class;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
VALUE
|
|
942
|
+
ca_face_strip_one (VALUE v)
|
|
943
|
+
{
|
|
944
|
+
CArray *c;
|
|
945
|
+
TypedData_Get_Struct(v, CArray, &carray_data_type, c);
|
|
946
|
+
return ca_is_face(c) ? rb_ca_parent(v) : v;
|
|
947
|
+
}
|
|
948
|
+
|
|
614
949
|
/* CArray.face_state_portable? — class method on CArray. Subclasses
|
|
615
950
|
(Face classes) override by defining their own `def self.face_state_portable?`.
|
|
616
951
|
This default returns true (= 1) for non-Face CArray classes; the actual
|
|
@@ -621,6 +956,57 @@ rb_ca_s_face_state_portable_p (VALUE klass)
|
|
|
621
956
|
return Qtrue;
|
|
622
957
|
}
|
|
623
958
|
|
|
959
|
+
/* ca.__orderable_storage__ -- whether ca's storage holds its values, in
|
|
960
|
+
their order, so that a lookup may compare the storage: true for an array
|
|
961
|
+
that is not a Face and for a Face that declares
|
|
962
|
+
CA_FLAG_FACE_ORDERABLE_STORAGE, false for a Face whose cells encode the
|
|
963
|
+
value (a const string's ranges, a categorical's codes). */
|
|
964
|
+
static VALUE
|
|
965
|
+
rb_ca_orderable_storage_p (VALUE self)
|
|
966
|
+
{
|
|
967
|
+
CArray *ca;
|
|
968
|
+
GetCArray(self, ca);
|
|
969
|
+
if ( ! ca_is_face(ca) ) return Qtrue;
|
|
970
|
+
return ca_test_flag(ca, CA_FLAG_FACE_ORDERABLE_STORAGE) ? Qtrue : Qfalse;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/* ca.__comparable_storage__ -- whether ca's storage holds its values as
|
|
974
|
+
they are, so that a plain operand may be compared with the storage: true
|
|
975
|
+
for an array that is not a Face and for a Face that declares
|
|
976
|
+
CA_FLAG_FACE_COMPARABLE_STORAGE. */
|
|
977
|
+
static VALUE
|
|
978
|
+
rb_ca_comparable_storage_p (VALUE self)
|
|
979
|
+
{
|
|
980
|
+
CArray *ca;
|
|
981
|
+
GetCArray(self, ca);
|
|
982
|
+
if ( ! ca_is_face(ca) ) return Qtrue;
|
|
983
|
+
return ca_test_flag(ca, CA_FLAG_FACE_COMPARABLE_STORAGE) ? Qtrue : Qfalse;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/* ca.__face_storage__ -- the storage under a Face (ca itself when it is not
|
|
987
|
+
a Face). */
|
|
988
|
+
static VALUE
|
|
989
|
+
rb_ca_face_storage (VALUE self)
|
|
990
|
+
{
|
|
991
|
+
return rb_ca_strip_face_value(self);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/* ca.__reconcile_operand__(operand, name) -- operand brought into ca's
|
|
995
|
+
storage space by the rule every operand family follows
|
|
996
|
+
(ca_face_reconcile_operand for a Face, ca_face_operand_descend for an
|
|
997
|
+
array that is not one). For the families written in Ruby. */
|
|
998
|
+
static VALUE
|
|
999
|
+
rb_ca_reconcile_operand (VALUE self, VALUE operand, VALUE rname)
|
|
1000
|
+
{
|
|
1001
|
+
CArray *ca;
|
|
1002
|
+
const char *name = StringValueCStr(rname);
|
|
1003
|
+
GetCArray(self, ca);
|
|
1004
|
+
if ( ca_is_face(ca) ) {
|
|
1005
|
+
return ca_face_reconcile_operand(self, operand, name);
|
|
1006
|
+
}
|
|
1007
|
+
return ca_face_operand_descend(operand, name);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
624
1010
|
/* CArray#face_lift(face_parent) — Ruby surface for ca_face_lift.
|
|
625
1011
|
Used by CArray.stack to re-wrap a raw CAStack with the homogeneous
|
|
626
1012
|
Face class carried by face_parent (typically list[0] after the
|
|
@@ -642,21 +1028,19 @@ rb_ca_face_lift_method (VALUE self, VALUE face_parent)
|
|
|
642
1028
|
|
|
643
1029
|
/* ca_face_reconcile_comparison(pself, pother) — Face gate for the element-
|
|
644
1030
|
* wise comparison operators (< <= > >=, eq, ne; <=> composes from > and <).
|
|
645
|
-
* Mirrors the search query gate (
|
|
1031
|
+
* Mirrors the search query gate (docs/authoring/FaceOrderingSearch.md): when the LHS
|
|
646
1032
|
* is a Face over NUMERIC storage, memcmp on the surface fixlen bytes would
|
|
647
1033
|
* mis-order the storage, so descend to storage (ORDERABLE licenses that the
|
|
648
1034
|
* numeric order equals the surface order) and reconcile the RHS:
|
|
649
1035
|
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
*
|
|
653
|
-
* - RHS is plain (bare number / non-Face array / Scalar): a direct storage
|
|
654
|
-
* compare, which only a COMPARABLE self licenses -- a non-COMPARABLE
|
|
655
|
-
* Face (e.g. a unit-bearing CATime) rejects it.
|
|
1036
|
+
* the RHS goes through ca_face_reconcile_operand: a COMPARABLE self takes
|
|
1037
|
+
* a plain RHS or a COMPARABLE Face, a self with to_comparable brings any
|
|
1038
|
+
* RHS into its space, and anything else is refused.
|
|
656
1039
|
*
|
|
657
|
-
* A Face over FIXLEN storage (CARecord / string faces)
|
|
1040
|
+
* A Face over FIXLEN storage (CARecord / string faces) keeps its Face:
|
|
658
1041
|
* memcmp on its bytes is already the correct order/equality, same as a plain
|
|
659
|
-
* fixlen array. Both operands are rebound
|
|
1042
|
+
* fixlen array; only the RHS is reconciled. Both operands are rebound via
|
|
1043
|
+
* *pself / *pother.
|
|
660
1044
|
* No-op when self is not a Face. */
|
|
661
1045
|
void
|
|
662
1046
|
ca_face_reconcile_comparison (volatile VALUE *pself, volatile VALUE *pother)
|
|
@@ -674,52 +1058,26 @@ ca_face_reconcile_comparison (volatile VALUE *pself, volatile VALUE *pother)
|
|
|
674
1058
|
|
|
675
1059
|
storage = ca_strip_face(sc);
|
|
676
1060
|
if ( storage->data_type == CA_FIXLEN ) {
|
|
677
|
-
/* genuine fixlen semantics: memcmp is the correct comparison,
|
|
678
|
-
|
|
1061
|
+
/* genuine fixlen semantics: memcmp is the correct comparison, so self
|
|
1062
|
+
keeps its Face (same result as a plain fixlen array) and only the
|
|
1063
|
+
operand is brought to bytes of the same meaning. */
|
|
1064
|
+
*pother = ca_face_reconcile_operand(self, other, "comparison");
|
|
679
1065
|
return;
|
|
680
1066
|
}
|
|
681
1067
|
|
|
682
1068
|
if ( ! ca_test_flag(sc, CA_FLAG_FACE_ORDERABLE_STORAGE) ) {
|
|
683
|
-
|
|
684
|
-
"comparison: Face operand (%s) is not orderable by storage; "
|
|
685
|
-
"use ca.parent to descend to storage",
|
|
686
|
-
rb_obj_classname(self));
|
|
1069
|
+
ca_face_refuse_order("comparison", self, "compare");
|
|
687
1070
|
}
|
|
688
1071
|
|
|
689
1072
|
{
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
other_is_face = ca_is_face(oc);
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
if ( comparable ) {
|
|
701
|
-
/* directly comparable Face reference: strip a Face operand, take a
|
|
702
|
-
plain operand as-is (storage compare is licensed). */
|
|
703
|
-
if ( other_is_face ) {
|
|
704
|
-
other = rb_ca_strip_face_value(other);
|
|
705
|
-
}
|
|
1073
|
+
int other_was_scalar = ! RTEST(rb_obj_is_carray(other));
|
|
1074
|
+
other = ca_face_reconcile_operand(self, other, "comparison");
|
|
1075
|
+
/* to_comparable lifts a scalar operand to a length-1 array; unwrap it
|
|
1076
|
+
so the comparison stays array-vs-scalar instead of a shape check
|
|
1077
|
+
against [1] (which only a 1-D reference would pass). */
|
|
1078
|
+
if ( other_was_scalar && RTEST(rb_obj_is_carray(other)) ) {
|
|
1079
|
+
other = rb_ca_fetch_addr(other, 0);
|
|
706
1080
|
}
|
|
707
|
-
else if ( rb_respond_to(self_ref, rb_intern("to_comparable")) ) {
|
|
708
|
-
/* non-COMPARABLE Face reference: the reference brings the operand into
|
|
709
|
-
its own space (unit alignment / instant lift), whatever the operand
|
|
710
|
-
type -- Face CArray, our Scalar, a Ruby Time / DateTime, etc. The
|
|
711
|
-
reference's to_comparable raises if it cannot reconcile it. */
|
|
712
|
-
other = rb_funcall(self_ref, rb_intern("to_comparable"), 1, other);
|
|
713
|
-
other = rb_ca_strip_face_value(other);
|
|
714
|
-
}
|
|
715
|
-
else {
|
|
716
|
-
rb_raise(rb_eArgError,
|
|
717
|
-
"comparison: non-comparable Face reference (%s) has no "
|
|
718
|
-
"to_comparable to reconcile the operand; use ca.parent to "
|
|
719
|
-
"compare the hidden storage explicitly",
|
|
720
|
-
rb_obj_classname(self_ref));
|
|
721
|
-
}
|
|
722
|
-
|
|
723
1081
|
*pself = rb_ca_strip_face_value(self);
|
|
724
1082
|
*pother = other;
|
|
725
1083
|
}
|
|
@@ -747,4 +1105,12 @@ Init_ca_face (void)
|
|
|
747
1105
|
rb_define_singleton_method(rb_cCArray, "face_state_portable?",
|
|
748
1106
|
rb_ca_s_face_state_portable_p, 0);
|
|
749
1107
|
rb_define_method(rb_cCArray, "face_lift", rb_ca_face_lift_method, 1);
|
|
1108
|
+
rb_define_private_method(rb_cCArray, "__orderable_storage__",
|
|
1109
|
+
rb_ca_orderable_storage_p, 0);
|
|
1110
|
+
rb_define_private_method(rb_cCArray, "__comparable_storage__",
|
|
1111
|
+
rb_ca_comparable_storage_p, 0);
|
|
1112
|
+
rb_define_private_method(rb_cCArray, "__face_storage__",
|
|
1113
|
+
rb_ca_face_storage, 0);
|
|
1114
|
+
rb_define_private_method(rb_cCArray, "__reconcile_operand__",
|
|
1115
|
+
rb_ca_reconcile_operand, 2);
|
|
750
1116
|
}
|