carray 3.0.6 → 3.0.7
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 +110 -0
- data/README.md +24 -3
- data/carray.gemspec +1 -1
- data/ext/ca_axis_group.c +6 -6
- data/ext/ca_binop_dispatch.c +8 -0
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +7 -7
- data/ext/ca_kernel_iterator.h +6 -4
- data/ext/ca_obj_array.c +4 -4
- data/ext/ca_obj_bincmp.c +19 -3
- data/ext/ca_obj_binop.c +36 -11
- data/ext/ca_obj_bitarray.c +2 -4
- data/ext/ca_obj_bitfield.c +86 -4
- data/ext/ca_obj_byte_swap.c +2 -4
- data/ext/ca_obj_const_string.c +422 -257
- data/ext/ca_obj_face.c +71 -33
- data/ext/ca_obj_fake.c +112 -13
- data/ext/ca_obj_farray.c +7 -1
- data/ext/ca_obj_fixlen_string.c +51 -17
- data/ext/ca_obj_grid.c +12 -7
- data/ext/ca_obj_meld.c +5 -5
- data/ext/ca_obj_monop.c +65 -39
- data/ext/ca_obj_object.c +9 -9
- data/ext/ca_obj_reduce.c +2 -4
- data/ext/ca_obj_refer.c +104 -10
- data/ext/ca_obj_repeat.c +1 -1
- data/ext/ca_obj_roll.c +2 -4
- data/ext/ca_obj_select.c +8 -6
- data/ext/ca_obj_select_axis.c +8 -6
- data/ext/ca_obj_stack.c +5 -5
- data/ext/ca_obj_stride.c +46 -8
- data/ext/ca_obj_string.c +2 -2
- data/ext/ca_obj_tile.c +2 -4
- data/ext/ca_obj_triop.c +15 -12
- data/ext/ca_obj_window.c +22 -15
- data/ext/ca_op_ipower.c +63 -15
- data/ext/ca_op_powi.h +6 -29
- data/ext/ca_sort_kernels.h +3 -0
- data/ext/ca_sweep_engine.c +90 -23
- data/ext/ca_sweep_engine.h +5 -6
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +3 -1
- data/ext/carray_access.c +98 -39
- data/ext/carray_address_basis.c +98 -24
- data/ext/carray_broadcast.c +2 -2
- data/ext/carray_call_cfunc.c +5 -8
- data/ext/carray_cast.c +311 -37
- data/ext/carray_cast_func.rb +37 -5
- data/ext/carray_conversion.c +56 -2
- data/ext/carray_copy.c +24 -0
- data/ext/carray_core.c +69 -6
- data/ext/carray_count.c +28 -9
- data/ext/carray_element.c +9 -3
- data/ext/carray_factorize.c +11 -11
- data/ext/carray_histogram.c +2 -2
- data/ext/carray_index_classifier.c +7 -5
- data/ext/carray_internal.h +94 -0
- data/ext/carray_kernels_binop.c +55 -55
- data/ext/carray_kernels_init.c +14 -14
- data/ext/carray_kernels_monop.c +90 -140
- data/ext/carray_lazy.c +16 -1
- data/ext/carray_loop.c +9 -2
- data/ext/carray_mask.c +118 -11
- data/ext/carray_median_percentile.c +13 -8
- data/ext/carray_memory_view.c +41 -22
- data/ext/carray_operator.c +72 -11
- data/ext/carray_order.c +52 -9
- data/ext/carray_partition.c +1 -1
- data/ext/carray_random.c +1 -1
- data/ext/carray_round.c +24 -1
- data/ext/carray_scatter.c +4 -0
- data/ext/carray_segment.c +1 -1
- data/ext/carray_slab.c +13 -4
- data/ext/carray_sort.c +6 -3
- data/ext/carray_sort_kernel.c +24 -0
- data/ext/carray_struct.c +21 -6
- data/ext/carray_test.c +85 -39
- data/ext/carray_time_text.c +6 -0
- data/ext/carray_utils.c +124 -54
- data/ext/mk_call_cfunc.rb +6 -11
- data/ext/mkkernel.rb +37 -27
- data/ext/version.h +4 -4
- data/lib/carray/axis_group.rb +9 -6
- data/lib/carray/basics.rb +26 -8
- data/lib/carray/bincount_nd.rb +8 -2
- data/lib/carray/block_iterator.rb +48 -21
- data/lib/carray/categorical.rb +21 -8
- data/lib/carray/categorical_iterator.rb +2 -1
- data/lib/carray/conditional.rb +52 -4
- data/lib/carray/const_string.rb +74 -0
- data/lib/carray/construct.rb +2 -2
- data/lib/carray/core_extensions.rb +19 -68
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/fixlen_string.rb +83 -1
- data/lib/carray/frame/column_verbs.rb +61 -6
- data/lib/carray/frame/concat.rb +50 -6
- data/lib/carray/frame/csv_parser.rb +13 -4
- data/lib/carray/frame/frame.rb +38 -6
- data/lib/carray/frame/group.rb +67 -40
- data/lib/carray/frame/io.rb +10 -5
- data/lib/carray/frame/join.rb +20 -6
- data/lib/carray/frame/records.rb +6 -4
- data/lib/carray/frame/reshape.rb +25 -5
- data/lib/carray/frame/verbs.rb +78 -25
- data/lib/carray/frame/windows.rb +30 -6
- data/lib/carray/fuse_source.rb +4 -2
- data/lib/carray/iterator.rb +8 -0
- data/lib/carray/key_windows.rb +10 -4
- data/lib/carray/lazy.rb +12 -17
- data/lib/carray/methods/bin.rb +3 -0
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/factorize.rb +2 -0
- data/lib/carray/methods/gather_nd.rb +4 -1
- data/lib/carray/methods/is_in.rb +23 -3
- data/lib/carray/methods/locate_addr.rb +63 -12
- data/lib/carray/methods/repeat.rb +11 -1
- data/lib/carray/record_order.rb +35 -6
- data/lib/carray/runtime.rb +10 -0
- data/lib/carray/segment_iterator.rb +19 -16
- data/lib/carray/serialize.rb +22 -0
- data/lib/carray/slab_iterator.rb +1 -1
- data/lib/carray/stack.rb +3 -3
- data/lib/carray/string.rb +6 -6
- data/lib/carray/string_operation_extension.rb +25 -4
- data/lib/carray/struct_builder.rb +4 -1
- data/lib/carray/time.rb +190 -46
- data/lib/carray/window_iterator.rb +48 -12
- data/yard-stubs/ca_obj_bitfield.rb +4 -1
- data/yard-stubs/ca_obj_refer.rb +3 -0
- data/yard-stubs/ca_obj_window.rb +2 -1
- data/yard-stubs/carray_access.rb +4 -2
- data/yard-stubs/carray_cast.rb +6 -0
- data/yard-stubs/carray_count.rb +6 -3
- data/yard-stubs/carray_math.rb +5 -0
- data/yard-stubs/carray_order.rb +6 -0
- data/yard-stubs/carray_scatter.rb +2 -1
- data/yard-stubs/carray_test.rb +18 -5
- metadata +2 -2
data/ext/carray_cast.c
CHANGED
|
@@ -607,10 +607,11 @@ OBJ2BOOL (VALUE v)
|
|
|
607
607
|
else if ( v == Qtrue ) {
|
|
608
608
|
return 1;
|
|
609
609
|
}
|
|
610
|
-
else if (
|
|
611
|
-
|
|
610
|
+
else if ( FIXNUM_P(v) ) {
|
|
611
|
+
/* an Integer past a Fixnum is no 0 or 1, and is refused below */
|
|
612
|
+
long flag = FIX2LONG(v);
|
|
612
613
|
if ( flag == 0 || flag == 1 ) {
|
|
613
|
-
return flag;
|
|
614
|
+
return (boolean8_t) flag;
|
|
614
615
|
}
|
|
615
616
|
}
|
|
616
617
|
{
|
|
@@ -638,7 +639,7 @@ ca_str_nonfinite (const char *str, double *out)
|
|
|
638
639
|
if ( ! strcasecmp(str, "nan")
|
|
639
640
|
|| ! strcasecmp(str, "+nan")
|
|
640
641
|
|| ! strcasecmp(str, "-nan") ) {
|
|
641
|
-
*out = 0.0/0.0
|
|
642
|
+
*out = NAN; /* 0.0/0.0 sets the sign bit on x86 */
|
|
642
643
|
return 1;
|
|
643
644
|
}
|
|
644
645
|
else if ( ! strcasecmp(str, "inf")
|
|
@@ -831,6 +832,40 @@ ca_obj2integer_ok (VALUE val, int8_t wide_type, void *wide, VALUE *integer)
|
|
|
831
832
|
return 1;
|
|
832
833
|
}
|
|
833
834
|
|
|
835
|
+
/* The to_type reader of an object cell for an integer type: a number that
|
|
836
|
+
is not an Integer (Float, Rational, BigDecimal, Complex) and does not fit
|
|
837
|
+
the type is a missing value, as a float array's cell is. An Integer
|
|
838
|
+
keeps its low bytes (the readers below). Returns 1 when the cell may be
|
|
839
|
+
read on. */
|
|
840
|
+
int
|
|
841
|
+
ca_obj_number_fits_integer (VALUE val, int8_t data_type)
|
|
842
|
+
{
|
|
843
|
+
int state = 0;
|
|
844
|
+
volatile VALUE integer;
|
|
845
|
+
if ( RB_INTEGER_TYPE_P(val) || NIL_P(val) || RB_TYPE_P(val, T_STRING) ) {
|
|
846
|
+
return 1;
|
|
847
|
+
}
|
|
848
|
+
/* protect: converts the caller's value and reports failure; nothing is held */
|
|
849
|
+
integer = rb_protect(ca_kernel_integer, val, &state);
|
|
850
|
+
if ( state ) {
|
|
851
|
+
rb_set_errinfo(Qnil);
|
|
852
|
+
return 1; /* the reader fails it on its own */
|
|
853
|
+
}
|
|
854
|
+
return ca_integer_range_side(integer, data_type) == 0;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/* The low bytes of an Integer in two's complement, for the _ok readers
|
|
858
|
+
below: an Integer wider than the C type is cut to it, as an Integer that
|
|
859
|
+
fits a long is when the caller narrows it to the cell's type. These
|
|
860
|
+
readers report failure through their return value and do not raise, so
|
|
861
|
+
a Bignum cannot go through NUM2LONG and friends. */
|
|
862
|
+
static void
|
|
863
|
+
ca_integer_low_bytes (VALUE integer, void *out, size_t size)
|
|
864
|
+
{
|
|
865
|
+
rb_integer_pack(integer, out, 1, size, 0,
|
|
866
|
+
INTEGER_PACK_2COMP | INTEGER_PACK_NATIVE_BYTE_ORDER);
|
|
867
|
+
}
|
|
868
|
+
|
|
834
869
|
int
|
|
835
870
|
rb_obj2long_ok (VALUE val, long *out)
|
|
836
871
|
{
|
|
@@ -843,7 +878,12 @@ rb_obj2long_ok (VALUE val, long *out)
|
|
|
843
878
|
if ( ! ca_obj2integer_ok(val, CA_INT64, &wide, &integer) ) {
|
|
844
879
|
return 0;
|
|
845
880
|
}
|
|
846
|
-
|
|
881
|
+
if ( NIL_P(integer) ) {
|
|
882
|
+
*out = (long) wide;
|
|
883
|
+
}
|
|
884
|
+
else {
|
|
885
|
+
ca_integer_low_bytes(integer, out, sizeof(*out));
|
|
886
|
+
}
|
|
847
887
|
return 1;
|
|
848
888
|
}
|
|
849
889
|
|
|
@@ -859,7 +899,12 @@ rb_obj2ulong_ok (VALUE val, unsigned long *out)
|
|
|
859
899
|
if ( ! ca_obj2integer_ok(val, CA_UINT64, &wide, &integer) ) {
|
|
860
900
|
return 0;
|
|
861
901
|
}
|
|
862
|
-
|
|
902
|
+
if ( NIL_P(integer) ) {
|
|
903
|
+
*out = (unsigned long) wide;
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
ca_integer_low_bytes(integer, out, sizeof(*out));
|
|
907
|
+
}
|
|
863
908
|
return 1;
|
|
864
909
|
}
|
|
865
910
|
|
|
@@ -875,7 +920,12 @@ rb_obj2ll_ok (VALUE val, long long *out)
|
|
|
875
920
|
if ( ! ca_obj2integer_ok(val, CA_INT64, &wide, &integer) ) {
|
|
876
921
|
return 0;
|
|
877
922
|
}
|
|
878
|
-
|
|
923
|
+
if ( NIL_P(integer) ) {
|
|
924
|
+
*out = (long long) wide;
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
ca_integer_low_bytes(integer, out, sizeof(*out));
|
|
928
|
+
}
|
|
879
929
|
return 1;
|
|
880
930
|
}
|
|
881
931
|
|
|
@@ -891,7 +941,12 @@ rb_obj2ull_ok (VALUE val, unsigned long long *out)
|
|
|
891
941
|
if ( ! ca_obj2integer_ok(val, CA_UINT64, &wide, &integer) ) {
|
|
892
942
|
return 0;
|
|
893
943
|
}
|
|
894
|
-
|
|
944
|
+
if ( NIL_P(integer) ) {
|
|
945
|
+
*out = (unsigned long long) wide;
|
|
946
|
+
}
|
|
947
|
+
else {
|
|
948
|
+
ca_integer_low_bytes(integer, out, sizeof(*out));
|
|
949
|
+
}
|
|
895
950
|
return 1;
|
|
896
951
|
}
|
|
897
952
|
|
|
@@ -1021,6 +1076,42 @@ ca_cast_block_with_mask (ca_size_t n, void *ap1, void *ptr1,
|
|
|
1021
1076
|
ca_cast_func_table[ca1->data_type][ca2->data_type](n, ca1, ptr1, ca2, ptr2, m);
|
|
1022
1077
|
}
|
|
1023
1078
|
|
|
1079
|
+
/* A store and a cast view: the masked cells are left alone and every other
|
|
1080
|
+
cell is converted as it is with no mask at all, so that the answer for a
|
|
1081
|
+
cell does not depend on another cell being masked. An object cell needs
|
|
1082
|
+
this: the table's loop with a mask is #to_type's, which wraps an integer
|
|
1083
|
+
the cell cannot hold and masks a value it cannot read. */
|
|
1084
|
+
void
|
|
1085
|
+
ca_cast_block_skip_masked (ca_size_t n, void *ap1, void *ptr1,
|
|
1086
|
+
void *ap2, void *ptr2, boolean8_t *m)
|
|
1087
|
+
{
|
|
1088
|
+
CArray *ca1 = (CArray *) ap1;
|
|
1089
|
+
CArray *ca2 = (CArray *) ap2;
|
|
1090
|
+
char *p1 = (char *) ptr1;
|
|
1091
|
+
char *p2 = (char *) ptr2;
|
|
1092
|
+
ca_size_t i = 0;
|
|
1093
|
+
|
|
1094
|
+
if ( m == NULL ) {
|
|
1095
|
+
ca_cast_block(n, ap1, ptr1, ap2, ptr2);
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
if ( ca1->data_type != CA_OBJECT ) {
|
|
1099
|
+
ca_cast_block_with_mask(n, ap1, ptr1, ap2, ptr2, m);
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
while ( i < n ) {
|
|
1103
|
+
ca_size_t j;
|
|
1104
|
+
if ( m[i] ) {
|
|
1105
|
+
i++;
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
for ( j = i; j < n && ! m[j]; j++ ) {
|
|
1109
|
+
}
|
|
1110
|
+
ca_cast_block(j - i, ap1, p1 + i * ca1->bytes, ap2, p2 + i * ca2->bytes);
|
|
1111
|
+
i = j;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1024
1115
|
VALUE
|
|
1025
1116
|
ca_ptr2obj (void *ap, void *ptr)
|
|
1026
1117
|
{
|
|
@@ -1147,32 +1238,32 @@ rb_ca_face_numeric_projection (VALUE self, CArray *ca)
|
|
|
1147
1238
|
|
|
1148
1239
|
if ( ! rb_respond_to(self, id_to_numeric) ) {
|
|
1149
1240
|
rb_raise(rb_eTypeError,
|
|
1150
|
-
"%
|
|
1241
|
+
"%"PRIsVALUE" declares no numeric conversion: define #to_numeric to say "
|
|
1151
1242
|
"how its values become numbers, or take the surface with "
|
|
1152
1243
|
"to_type(:object) / the storage with #parent",
|
|
1153
|
-
|
|
1244
|
+
rb_obj_class(self));
|
|
1154
1245
|
}
|
|
1155
1246
|
|
|
1156
1247
|
num = rb_funcall(self, id_to_numeric, 0);
|
|
1157
1248
|
|
|
1158
1249
|
if ( ! rb_obj_is_carray(num) ) {
|
|
1159
1250
|
rb_raise(rb_eTypeError,
|
|
1160
|
-
"%
|
|
1161
|
-
|
|
1251
|
+
"%"PRIsVALUE"#to_numeric must return a CArray (got %"PRIsVALUE")",
|
|
1252
|
+
rb_obj_class(self), rb_obj_class(num));
|
|
1162
1253
|
}
|
|
1163
1254
|
|
|
1164
1255
|
TypedData_Get_Struct(num, CArray, &carray_data_type, cn);
|
|
1165
1256
|
|
|
1166
1257
|
if ( ca_is_face(cn) ) {
|
|
1167
1258
|
rb_raise(rb_eTypeError,
|
|
1168
|
-
"%
|
|
1169
|
-
|
|
1259
|
+
"%"PRIsVALUE"#to_numeric must return a plain CArray, not a Face (got %"PRIsVALUE")",
|
|
1260
|
+
rb_obj_class(self), rb_obj_class(num));
|
|
1170
1261
|
}
|
|
1171
1262
|
|
|
1172
1263
|
if ( cn->elements != ca->elements ) {
|
|
1173
1264
|
rb_raise(rb_eArgError,
|
|
1174
|
-
"%
|
|
1175
|
-
|
|
1265
|
+
"%"PRIsVALUE"#to_numeric returned %lld elements, expected %lld",
|
|
1266
|
+
rb_obj_class(self),
|
|
1176
1267
|
(long long) cn->elements, (long long) ca->elements);
|
|
1177
1268
|
}
|
|
1178
1269
|
|
|
@@ -1584,15 +1675,15 @@ ca_type_adapt_view (VALUE obj, VALUE rtype, int8_t data_type, int mode)
|
|
|
1584
1675
|
return rb_ca_to_type_internal(1, args, obj);
|
|
1585
1676
|
case CA_ADAPT_WRITABLE:
|
|
1586
1677
|
rb_raise(rb_eTypeError,
|
|
1587
|
-
"%
|
|
1678
|
+
"%"PRIsVALUE" has no writable view in another data_type: the writes "
|
|
1588
1679
|
"would land on the storage its surface hides -- wrap "
|
|
1589
1680
|
"#parent to reach that storage",
|
|
1590
|
-
|
|
1681
|
+
rb_obj_class(obj));
|
|
1591
1682
|
default:
|
|
1592
1683
|
rb_raise(rb_eTypeError,
|
|
1593
|
-
"%
|
|
1684
|
+
"%"PRIsVALUE" has no view of its values in another data_type: "
|
|
1594
1685
|
"#to_type gives the values, #parent the raw storage",
|
|
1595
|
-
|
|
1686
|
+
rb_obj_class(obj));
|
|
1596
1687
|
}
|
|
1597
1688
|
}
|
|
1598
1689
|
|
|
@@ -2158,7 +2249,7 @@ rb_ca_cast (volatile VALUE self)
|
|
|
2158
2249
|
string semantics those bodies implement (min-width memcmp with a length
|
|
2159
2250
|
tiebreak); this is only about a scalar standing in for a cell. */
|
|
2160
2251
|
static int
|
|
2161
|
-
ca_fixlen_scalar_operand (volatile VALUE *scalar, VALUE reference)
|
|
2252
|
+
ca_fixlen_scalar_operand (volatile VALUE *scalar, volatile VALUE reference)
|
|
2162
2253
|
{
|
|
2163
2254
|
CArray *cr;
|
|
2164
2255
|
/* A String is the only operand that means a cell value here. A Regexp
|
|
@@ -2183,6 +2274,24 @@ ca_fixlen_scalar_operand (volatile VALUE *scalar, VALUE reference)
|
|
|
2183
2274
|
return 1;
|
|
2184
2275
|
}
|
|
2185
2276
|
|
|
2277
|
+
/* UNDEF as the scalar side of an operation with an array: a masked
|
|
2278
|
+
scalar of the array's own data_type and width. UNDEF has no value, so it
|
|
2279
|
+
cannot decide the type of the result; read as a Ruby object it would make
|
|
2280
|
+
an integer, boolean or fixlen operation answer an object array, while a
|
|
2281
|
+
float one kept its type. An operation the data type does not take
|
|
2282
|
+
(fixlen `+`) is refused as for any other operand. */
|
|
2283
|
+
static int
|
|
2284
|
+
ca_undef_scalar_operand (volatile VALUE *scalar, volatile VALUE reference)
|
|
2285
|
+
{
|
|
2286
|
+
CArray *cr;
|
|
2287
|
+
if ( *scalar != CA_UNDEF || ! rb_obj_is_carray(reference) ) {
|
|
2288
|
+
return 0;
|
|
2289
|
+
}
|
|
2290
|
+
TypedData_Get_Struct(reference, CArray, &carray_data_type, cr);
|
|
2291
|
+
*scalar = rb_cscalar_new_with_value(cr->data_type, cr->bytes, CA_UNDEF);
|
|
2292
|
+
return 1;
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2186
2295
|
/* Where a Ruby Integer falls against the range of integer data type `dt`:
|
|
2187
2296
|
-1 below it, 1 above it, 0 inside. Anything but an Integer, and a
|
|
2188
2297
|
non-integer `dt`, answer 0. */
|
|
@@ -2249,12 +2358,22 @@ ca_obj2integer_fitting (VALUE v, int8_t data_type)
|
|
|
2249
2358
|
return integer;
|
|
2250
2359
|
}
|
|
2251
2360
|
|
|
2361
|
+
VALUE
|
|
2362
|
+
ca_obj2integer_store (CArray *dst, VALUE v, int8_t data_type)
|
|
2363
|
+
{
|
|
2364
|
+
CArray *field = dst ? ca_bitfield_beneath(dst) : NULL;
|
|
2365
|
+
if ( field ) {
|
|
2366
|
+
return ca_bitfield_wrap_integer(field, v);
|
|
2367
|
+
}
|
|
2368
|
+
return ca_obj2integer_fitting(v, data_type);
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2252
2371
|
/* A Ruby Integer operand against an integer array is taken in the array's
|
|
2253
2372
|
own data type, refused when it does not fit (ca_check_integer_fits).
|
|
2254
2373
|
Widening instead would make the result's type depend on a scalar's
|
|
2255
2374
|
value. A Float, a Face and an object array keep the coercion below. */
|
|
2256
2375
|
static int
|
|
2257
|
-
ca_integer_scalar_operand (volatile VALUE *scalar, VALUE reference)
|
|
2376
|
+
ca_integer_scalar_operand (volatile VALUE *scalar, volatile VALUE reference)
|
|
2258
2377
|
{
|
|
2259
2378
|
CArray *cr;
|
|
2260
2379
|
if ( ! RB_INTEGER_TYPE_P(*scalar) || ! rb_obj_is_carray(reference) ) {
|
|
@@ -2278,7 +2397,7 @@ ca_integer_scalar_operand (volatile VALUE *scalar, VALUE reference)
|
|
|
2278
2397
|
promoted together. Against an object array, a Face or a fixlen array an
|
|
2279
2398
|
Array stays one value. */
|
|
2280
2399
|
static int
|
|
2281
|
-
ca_array_operand (volatile VALUE *ary, VALUE reference, int both)
|
|
2400
|
+
ca_array_operand (volatile VALUE *ary, volatile VALUE reference, int both)
|
|
2282
2401
|
{
|
|
2283
2402
|
CArray *cr;
|
|
2284
2403
|
volatile VALUE flat, probe_self, probe;
|
|
@@ -2368,13 +2487,105 @@ ca_operand_from_memory_view (VALUE obj)
|
|
|
2368
2487
|
its class. A Face reports the data type of its storage ("fixlen" for a
|
|
2369
2488
|
time, a categorical, a record or a string column), which says nothing
|
|
2370
2489
|
about what the operand is. */
|
|
2371
|
-
static
|
|
2490
|
+
static VALUE
|
|
2372
2491
|
ca_coerce_operand_name (VALUE obj, CArray *ca)
|
|
2373
2492
|
{
|
|
2374
2493
|
if ( ca_is_face(ca) ) {
|
|
2375
|
-
return
|
|
2494
|
+
return rb_obj_class(obj);
|
|
2495
|
+
}
|
|
2496
|
+
return rb_str_new_cstr(ca_type_name[ca->data_type]);
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
int
|
|
2500
|
+
ca_value_foreign_to (CArray *ca, VALUE v)
|
|
2501
|
+
{
|
|
2502
|
+
if ( ca_is_face(ca) || ca->data_type == CA_OBJECT || ca->data_type == CA_FIXLEN ) {
|
|
2503
|
+
return 0;
|
|
2504
|
+
}
|
|
2505
|
+
if ( v == Qtrue || v == Qfalse || v == CA_UNDEF || rb_obj_is_carray(v) ) {
|
|
2506
|
+
return 0;
|
|
2507
|
+
}
|
|
2508
|
+
if ( RTEST(rb_obj_is_kind_of(v, rb_cNumeric)) || RB_TYPE_P(v, T_ARRAY) ) {
|
|
2509
|
+
return 0;
|
|
2510
|
+
}
|
|
2511
|
+
if ( rb_respond_to(v, rb_intern("to_ca")) || rb_memory_view_available_p(v) ) {
|
|
2512
|
+
return 0;
|
|
2513
|
+
}
|
|
2514
|
+
return 1;
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
VALUE
|
|
2518
|
+
ca_truth_as_number (CArray *ca, VALUE v)
|
|
2519
|
+
{
|
|
2520
|
+
if ( ( v == Qtrue || v == Qfalse ) && ! ca_is_face(ca) &&
|
|
2521
|
+
( ca_is_integer_type(ca) || ca_is_float_type(ca) ||
|
|
2522
|
+
ca_is_complex_type(ca) ) ) {
|
|
2523
|
+
return INT2FIX(v == Qtrue);
|
|
2376
2524
|
}
|
|
2377
|
-
return
|
|
2525
|
+
return v;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
/* The name Ruby's coercion error gives a value: nil and a Symbol by
|
|
2529
|
+
themselves, anything else by its class. */
|
|
2530
|
+
static VALUE
|
|
2531
|
+
ca_foreign_value_name (VALUE v)
|
|
2532
|
+
{
|
|
2533
|
+
if ( NIL_P(v) || SYMBOL_P(v) ) {
|
|
2534
|
+
return rb_inspect(v);
|
|
2535
|
+
}
|
|
2536
|
+
return rb_class_name(CLASS_OF(v));
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
/* The Ruby class whose operator the array's cells answer for. */
|
|
2540
|
+
static const char *
|
|
2541
|
+
ca_cell_class_name (CArray *ca)
|
|
2542
|
+
{
|
|
2543
|
+
if ( ca_is_float_type(ca) ) return "Float";
|
|
2544
|
+
if ( ca_is_complex_type(ca) ) return "Complex";
|
|
2545
|
+
return "Integer";
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
void
|
|
2549
|
+
ca_refuse_foreign_operand (VALUE v, volatile VALUE array)
|
|
2550
|
+
{
|
|
2551
|
+
CArray *ca;
|
|
2552
|
+
if ( ! rb_obj_is_carray(array) ) {
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
GetCArray(array, ca);
|
|
2556
|
+
if ( ca_value_foreign_to(ca, v) ) {
|
|
2557
|
+
rb_raise(rb_eTypeError, "%s: %" PRIsVALUE " can't be coerced into %s",
|
|
2558
|
+
ca_calling_method_name(), ca_foreign_value_name(v),
|
|
2559
|
+
ca_cell_class_name(ca));
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
void
|
|
2564
|
+
ca_refuse_foreign_order (VALUE v, volatile VALUE array)
|
|
2565
|
+
{
|
|
2566
|
+
CArray *ca;
|
|
2567
|
+
if ( ! rb_obj_is_carray(array) ) {
|
|
2568
|
+
return;
|
|
2569
|
+
}
|
|
2570
|
+
GetCArray(array, ca);
|
|
2571
|
+
if ( ca_value_foreign_to(ca, v) ) {
|
|
2572
|
+
rb_raise(rb_eArgError, "%s: comparison of %s with %" PRIsVALUE " failed",
|
|
2573
|
+
ca_calling_method_name(), ca_cell_class_name(ca),
|
|
2574
|
+
ca_foreign_value_name(v));
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
/* true and false are the numbers 0 and 1 to an operator, as a boolean
|
|
2579
|
+
array is: an integer array reads them through ca_value_to_data_type, and
|
|
2580
|
+
a float or complex array reads them here rather than through Float(). */
|
|
2581
|
+
static int
|
|
2582
|
+
ca_truth_scalar_operand (volatile VALUE *scalar)
|
|
2583
|
+
{
|
|
2584
|
+
if ( *scalar == Qtrue || *scalar == Qfalse ) {
|
|
2585
|
+
*scalar = rb_cscalar_new_with_value(CA_BOOLEAN, 0, *scalar);
|
|
2586
|
+
return 1;
|
|
2587
|
+
}
|
|
2588
|
+
return 0;
|
|
2378
2589
|
}
|
|
2379
2590
|
|
|
2380
2591
|
void
|
|
@@ -2402,6 +2613,7 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
2402
2613
|
|
|
2403
2614
|
if ( ! rb_obj_is_carray(*self) ) {
|
|
2404
2615
|
self_is_object = 1;
|
|
2616
|
+
ca_refuse_foreign_operand(*self, *other);
|
|
2405
2617
|
if ( rb_ca_is_object_type(*other) ) {
|
|
2406
2618
|
*self = rb_cscalar_new_with_value(CA_OBJECT, 0, *self);
|
|
2407
2619
|
}
|
|
@@ -2414,12 +2626,18 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
2414
2626
|
*self = rb_cscalar_new_with_value(CA_CMPLX128, 0, *self);
|
|
2415
2627
|
}
|
|
2416
2628
|
#endif
|
|
2629
|
+
else if ( ca_undef_scalar_operand(self, *other) ) {
|
|
2630
|
+
/* the array's own data_type; see the helper above */
|
|
2631
|
+
}
|
|
2417
2632
|
else if ( ca_fixlen_scalar_operand(self, *other) ) {
|
|
2418
2633
|
/* width taken from the fixlen reference; see the helper above */
|
|
2419
2634
|
}
|
|
2420
2635
|
else if ( ca_integer_scalar_operand(self, *other) ) {
|
|
2421
2636
|
/* the array's own integer type; see the helper above */
|
|
2422
2637
|
}
|
|
2638
|
+
else if ( ca_truth_scalar_operand(self) ) {
|
|
2639
|
+
/* boolean, promoted with the array below */
|
|
2640
|
+
}
|
|
2423
2641
|
else if ( rb_ca_is_float_type(*other) ) {
|
|
2424
2642
|
*self = rb_cscalar_new_with_value(CA_FLOAT64, 0, *self);
|
|
2425
2643
|
}
|
|
@@ -2435,6 +2653,7 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
2435
2653
|
|
|
2436
2654
|
if ( ! rb_obj_is_carray(*other) ) {
|
|
2437
2655
|
other_is_object = 1;
|
|
2656
|
+
ca_refuse_foreign_operand(*other, *self);
|
|
2438
2657
|
|
|
2439
2658
|
if ( rb_ca_is_object_type(*self) ) {
|
|
2440
2659
|
*other = rb_cscalar_new_with_value(CA_OBJECT, 0, *other);
|
|
@@ -2448,12 +2667,18 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
2448
2667
|
*other = rb_cscalar_new_with_value(CA_CMPLX128, 0, *other);
|
|
2449
2668
|
}
|
|
2450
2669
|
#endif
|
|
2670
|
+
else if ( ca_undef_scalar_operand(other, *self) ) {
|
|
2671
|
+
/* the array's own data_type; see the helper above */
|
|
2672
|
+
}
|
|
2451
2673
|
else if ( ca_fixlen_scalar_operand(other, *self) ) {
|
|
2452
2674
|
/* width taken from the fixlen reference; see the helper above */
|
|
2453
2675
|
}
|
|
2454
2676
|
else if ( ca_integer_scalar_operand(other, *self) ) {
|
|
2455
2677
|
/* the array's own integer type; see the helper above */
|
|
2456
2678
|
}
|
|
2679
|
+
else if ( ca_truth_scalar_operand(other) ) {
|
|
2680
|
+
/* boolean, promoted with the array below */
|
|
2681
|
+
}
|
|
2457
2682
|
else if ( rb_ca_is_float_type(*self) ) {
|
|
2458
2683
|
*other = rb_cscalar_new_with_value(CA_FLOAT64, 0, *other);
|
|
2459
2684
|
}
|
|
@@ -2526,11 +2751,55 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
2526
2751
|
/* A data type the operation does not take, as `sqrt!` on an integer
|
|
2527
2752
|
array is refused (CArray::DataTypeError is a TypeError). */
|
|
2528
2753
|
rb_raise(rb_eCADataTypeError,
|
|
2529
|
-
"can't coerce carray with data_types of '%
|
|
2754
|
+
"can't coerce carray with data_types of '%"PRIsVALUE"' and '%"PRIsVALUE"'",
|
|
2530
2755
|
ca_coerce_operand_name(*self, ca),
|
|
2531
2756
|
ca_coerce_operand_name(*other, cb));
|
|
2532
2757
|
}
|
|
2533
2758
|
|
|
2759
|
+
/* The three operands of a three-operand expression at their common data_type.
|
|
2760
|
+
Pairs find that type, and they find it for operands that are not arrays
|
|
2761
|
+
yet. An array then goes to it in one step: taken through the pairs, it
|
|
2762
|
+
would pass through the type of the first pair (an int8 -1 becomes 255 in
|
|
2763
|
+
uint8 and stays 255 in uint64), and the answer would depend on the order
|
|
2764
|
+
of the operands. The arrays are then brought to one shape together
|
|
2765
|
+
(the size-1 broadcast of the pairs), after the cast: the cast starts from
|
|
2766
|
+
the operand as given, so a shape the pairs settled on is set again here. */
|
|
2767
|
+
void
|
|
2768
|
+
rb_ca_cast_three (volatile VALUE *v1, volatile VALUE *v2, volatile VALUE *v3)
|
|
2769
|
+
{
|
|
2770
|
+
volatile VALUE original[3];
|
|
2771
|
+
volatile VALUE *cast[3];
|
|
2772
|
+
CArray *ca;
|
|
2773
|
+
int8_t common;
|
|
2774
|
+
int i;
|
|
2775
|
+
|
|
2776
|
+
original[0] = *v1;
|
|
2777
|
+
original[1] = *v2;
|
|
2778
|
+
original[2] = *v3;
|
|
2779
|
+
cast[0] = v1;
|
|
2780
|
+
cast[1] = v2;
|
|
2781
|
+
cast[2] = v3;
|
|
2782
|
+
|
|
2783
|
+
rb_ca_cast_self_or_other(v1, v2);
|
|
2784
|
+
rb_ca_cast_self_or_other(v1, v3);
|
|
2785
|
+
rb_ca_cast_self_or_other(v2, v3);
|
|
2786
|
+
rb_ca_cast_self_or_other(v1, v2);
|
|
2787
|
+
|
|
2788
|
+
TypedData_Get_Struct(*v1, CArray, &carray_data_type, ca);
|
|
2789
|
+
common = ca->data_type;
|
|
2790
|
+
for ( i = 0; i < 3; i++ ) {
|
|
2791
|
+
if ( ! rb_obj_is_carray(original[i]) ) continue;
|
|
2792
|
+
TypedData_Get_Struct(original[i], CArray, &carray_data_type, ca);
|
|
2793
|
+
*cast[i] = ( ca->data_type != common && ! ca_is_face(ca) )
|
|
2794
|
+
? rb_ca_wrap_readonly(original[i], INT2NUM(common))
|
|
2795
|
+
: original[i];
|
|
2796
|
+
}
|
|
2797
|
+
ca_broadcast_pair(v1, v2);
|
|
2798
|
+
ca_broadcast_pair(v1, v3);
|
|
2799
|
+
ca_broadcast_pair(v2, v3);
|
|
2800
|
+
ca_broadcast_pair(v1, v2);
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2534
2803
|
/* Refuses a pair of arrays with no common data_type in the words of
|
|
2535
2804
|
rb_ca_cast_self_or_other (the eager operators'), and returns otherwise
|
|
2536
2805
|
without casting either. A lazy builder calls it before it works out
|
|
@@ -2927,10 +3196,10 @@ rb_ca_s_promote_list (int argc, VALUE *argv, VALUE klass)
|
|
|
2927
3196
|
TypedData_Get_Struct(elem, CArray, &carray_data_type, ca);
|
|
2928
3197
|
if ( ca_is_face(ca) ) {
|
|
2929
3198
|
rb_raise(rb_eArgError,
|
|
2930
|
-
"promote_list: data_type %
|
|
3199
|
+
"promote_list: data_type %"PRIsVALUE" cannot be applied to a list "
|
|
2931
3200
|
"containing Face elements (= Face cannot be coerced to "
|
|
2932
3201
|
"a primitive without losing identity)",
|
|
2933
|
-
|
|
3202
|
+
rb_inspect(data_type));
|
|
2934
3203
|
}
|
|
2935
3204
|
}
|
|
2936
3205
|
{
|
|
@@ -2998,12 +3267,17 @@ rb_ca_cast_other (VALUE *self, volatile VALUE *other)
|
|
|
2998
3267
|
ca_array_operand(other, *self, 0);
|
|
2999
3268
|
|
|
3000
3269
|
if ( ! rb_obj_is_carray(*other) ) {
|
|
3270
|
+
ca_refuse_foreign_operand(*other, *self);
|
|
3001
3271
|
if ( rb_ca_is_object_type(*self) ) {
|
|
3002
3272
|
*other = rb_cscalar_new_with_value(CA_OBJECT, 0, *other);
|
|
3003
3273
|
}
|
|
3004
|
-
else if (
|
|
3274
|
+
else if ( ca_undef_scalar_operand(other, *self) ||
|
|
3275
|
+
ca_fixlen_scalar_operand(other, *self) ) {
|
|
3005
3276
|
return; /* already the receiver's data_type and width */
|
|
3006
3277
|
}
|
|
3278
|
+
else if ( ca_truth_scalar_operand(other) ) {
|
|
3279
|
+
/* boolean, promoted with the array below */
|
|
3280
|
+
}
|
|
3007
3281
|
else if ( rb_ca_is_float_type(*self) ) {
|
|
3008
3282
|
*other = rb_cscalar_new_with_value(CA_FLOAT64, 0, *other);
|
|
3009
3283
|
}
|
|
@@ -3042,7 +3316,7 @@ rb_ca_cast_other (VALUE *self, volatile VALUE *other)
|
|
|
3042
3316
|
/* A data type the operation does not take, as `sqrt!` on an integer
|
|
3043
3317
|
array is refused (CArray::DataTypeError is a TypeError). */
|
|
3044
3318
|
rb_raise(rb_eCADataTypeError,
|
|
3045
|
-
"can't coerce carray with data_types of '%
|
|
3319
|
+
"can't coerce carray with data_types of '%"PRIsVALUE"' and '%"PRIsVALUE"'",
|
|
3046
3320
|
ca_coerce_operand_name(*self, ca),
|
|
3047
3321
|
ca_coerce_operand_name(*other, cb));
|
|
3048
3322
|
}
|
|
@@ -3205,8 +3479,8 @@ ca_cast_impl (int8_t data_type, int argc, VALUE *argv)
|
|
|
3205
3479
|
if ( argc == 2 && ! RTEST(rb_obj_is_kind_of(v, rb_cRange)) ) {
|
|
3206
3480
|
rb_raise(rb_eArgError,
|
|
3207
3481
|
"a step (the second argument) is only accepted "
|
|
3208
|
-
"when the first argument is a Range (got %
|
|
3209
|
-
|
|
3482
|
+
"when the first argument is a Range (got %"PRIsVALUE")",
|
|
3483
|
+
rb_obj_class(v));
|
|
3210
3484
|
}
|
|
3211
3485
|
|
|
3212
3486
|
if ( TYPE(v) == T_ARRAY ) {
|
|
@@ -3359,18 +3633,18 @@ rb_ca_cast_fixlen (int argc, VALUE *argv, VALUE self)
|
|
|
3359
3633
|
}
|
|
3360
3634
|
bytes = ( maxlen > 0 ) ? maxlen : 1; /* all empty: one NUL byte */
|
|
3361
3635
|
} else {
|
|
3362
|
-
bytes =
|
|
3636
|
+
bytes = ca_integer_arg(bytes_v, "bytes", NULL);
|
|
3363
3637
|
}
|
|
3364
3638
|
shape = rb_funcall(rb_cCArray, id_guess_array_shape_cast, 1, v);
|
|
3365
3639
|
ndim = RARRAY_LEN(shape);
|
|
3366
|
-
for ( i = 0; i < ndim; i++ ) dim[i] =
|
|
3640
|
+
for ( i = 0; i < ndim; i++ ) dim[i] = ca_integer_arg(rb_ary_entry(shape, i), "a dimension", NULL);
|
|
3367
3641
|
obj = rb_carray_new(CA_FIXLEN, (int8_t) ndim, dim, bytes, NULL);
|
|
3368
3642
|
rb_ca_store_all(obj, v);
|
|
3369
3643
|
return obj;
|
|
3370
3644
|
}
|
|
3371
3645
|
else if ( NIL_P(v) ) {
|
|
3372
3646
|
ca_size_t dim0 = 0;
|
|
3373
|
-
ca_size_t bytes = NIL_P(bytes_v) ? 1 :
|
|
3647
|
+
ca_size_t bytes = NIL_P(bytes_v) ? 1 : ca_integer_arg(bytes_v, "bytes", NULL);
|
|
3374
3648
|
return rb_carray_new(CA_FIXLEN, 1, &dim0, bytes, NULL);
|
|
3375
3649
|
}
|
|
3376
3650
|
else {
|
|
@@ -3387,7 +3661,7 @@ rb_ca_cast_fixlen (int argc, VALUE *argv, VALUE self)
|
|
|
3387
3661
|
check reports it. */
|
|
3388
3662
|
ca_size_t bytes = 0;
|
|
3389
3663
|
if ( ! NIL_P(bytes_v) ) {
|
|
3390
|
-
bytes =
|
|
3664
|
+
bytes = ca_integer_arg(bytes_v, "bytes", NULL);
|
|
3391
3665
|
}
|
|
3392
3666
|
else if ( RB_TYPE_P(v, T_STRING) ) {
|
|
3393
3667
|
bytes = ( RSTRING_LEN(v) > 0 ) ? RSTRING_LEN(v) : 1;
|
data/ext/carray_cast_func.rb
CHANGED
|
@@ -371,7 +371,29 @@ puts
|
|
|
371
371
|
lo_cmp = ( type2 == CA_INT64 ) ? ">=" : ">"
|
|
372
372
|
fits = "( v #{lo_cmp} #{lo} && v < #{hi} )"
|
|
373
373
|
fits = "( #{fits} && ! isnan(cimag(q1[k])) )" if complex
|
|
374
|
-
|
|
374
|
+
# The cells of a bit field view keep a float's integer part modulo
|
|
375
|
+
# 2 ** bits, as a Float stored on its own does (ca_obj2integer_store).
|
|
376
|
+
unless complex
|
|
377
|
+
num = [CA_UINT8, CA_UINT16, CA_UINT32, CA_UINT64].include?(type2) ? "rb_num2ull" : "NUM2LL"
|
|
378
|
+
nan_check << <<-END_FIELD.gsub(/^ {8}/, '')
|
|
379
|
+
if ( a2 && ca_bitfield_beneath(a2) ) {
|
|
380
|
+
for (k=0; k<n; k++) {
|
|
381
|
+
double v = (double) q1[k];
|
|
382
|
+
if ( m && m[k] ) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if ( ! isfinite(v) ) {
|
|
386
|
+
rb_raise(rb_eFloatDomainError, "%s: %s cannot be converted to %s",
|
|
387
|
+
ca_calling_method_name(), isinf(v) ? "an infinity" : "NaN",
|
|
388
|
+
ca_type_name[#{type_const[type2]}]);
|
|
389
|
+
}
|
|
390
|
+
q2[k] = (#{ctype2}) #{num}(ca_obj2integer_store(a2, rb_float_new(v), #{type_const[type2]}));
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
END_FIELD
|
|
395
|
+
end
|
|
396
|
+
nan_check << <<-END_CHECK.gsub(/^ {6}/, '')
|
|
375
397
|
for (k=0; k<n; k++) {
|
|
376
398
|
double v = (double) #{real};
|
|
377
399
|
if ( ( ! m || ! m[k] ) && ! #{fits} ) {
|
|
@@ -537,18 +559,28 @@ OBJECT.each do |type1|
|
|
|
537
559
|
# Ruby literal. Complex keeps its own reader.
|
|
538
560
|
if (INTEGER+FLOAT).include?(type2)
|
|
539
561
|
type_name = "CA_" + ctype2.sub(/_t\z/, "").upcase
|
|
562
|
+
# A number other than an Integer that does not fit an integer type
|
|
563
|
+
# is read as missing (ca_obj_number_fits_integer); an Integer keeps
|
|
564
|
+
# its low bytes.
|
|
565
|
+
fits = INTEGER.include?(type2) ?
|
|
566
|
+
"ca_obj_number_fits_integer(*p1, #{type_name}) && " : ""
|
|
540
567
|
read_ok = "( RB_TYPE_P(*p1, T_STRING) ? " \
|
|
541
568
|
"ca_decimal_string_to(*p1, #{type_name}, p2) : " \
|
|
542
|
-
"( #{conv_ok}(*p1, &tmp) ? ( *p2 = (#{ctype2}) tmp, 1 ) : 0 ) )"
|
|
569
|
+
"( #{fits}#{conv_ok}(*p1, &tmp) ? ( *p2 = (#{ctype2}) tmp, 1 ) : 0 ) )"
|
|
543
570
|
# A store refuses an integer the cell cannot hold
|
|
544
|
-
# (
|
|
571
|
+
# (ca_obj2integer_store); to_type, above, keeps the C conversion.
|
|
545
572
|
store_conv = if INTEGER.include?(type2)
|
|
546
573
|
num = [CA_UINT8, CA_UINT16, CA_UINT32, CA_UINT64].include?(type2) ? "rb_num2ull" : "NUM2LL"
|
|
547
|
-
"#{num}(
|
|
574
|
+
"#{num}(ca_obj2integer_store(a2, *p1, #{type_name}))"
|
|
548
575
|
else
|
|
549
576
|
"#{conv}(*p1)"
|
|
550
577
|
end
|
|
551
|
-
|
|
578
|
+
# The cells of a bit field view read a String through
|
|
579
|
+
# ca_obj2integer_store too (it keeps the value modulo 2 ** bits).
|
|
580
|
+
str_test = INTEGER.include?(type2) ?
|
|
581
|
+
"RB_TYPE_P(*p1, T_STRING) && ! ( a2 && ca_bitfield_beneath(a2) )" :
|
|
582
|
+
"RB_TYPE_P(*p1, T_STRING)"
|
|
583
|
+
read = "if ( #{str_test} ) { " \
|
|
552
584
|
"ca_decimal_string_store(*p1, #{type_name}, p2); } " \
|
|
553
585
|
"else { *p2 = (#{ctype2}) #{store_conv}; }"
|
|
554
586
|
else
|