carray 1.5.2 → 1.5.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +32 -0
  3. data/NEWS.md +56 -3
  4. data/README.md +34 -18
  5. data/Rakefile +1 -1
  6. data/TODO.md +5 -4
  7. data/carray.gemspec +10 -11
  8. data/ext/ca_obj_bitarray.c +4 -7
  9. data/ext/ca_obj_bitfield.c +3 -5
  10. data/ext/ca_obj_block.c +1 -6
  11. data/ext/ca_obj_refer.c +6 -8
  12. data/ext/ca_obj_unbound_repeat.c +21 -52
  13. data/ext/carray.h +4 -0
  14. data/ext/carray_access.c +77 -45
  15. data/ext/carray_attribute.c +16 -1
  16. data/ext/carray_cast.c +1 -1
  17. data/ext/carray_conversion.c +8 -1
  18. data/ext/carray_core.c +22 -16
  19. data/ext/carray_generate.c +3 -3
  20. data/ext/carray_mask.c +12 -2
  21. data/ext/carray_math.rb +20 -2
  22. data/ext/carray_numeric.c +32 -51
  23. data/ext/carray_order.c +159 -0
  24. data/ext/carray_test.c +13 -0
  25. data/ext/carray_undef.c +0 -8
  26. data/ext/carray_utils.c +126 -47
  27. data/ext/extconf.rb +13 -1
  28. data/ext/mkmath.rb +1 -1
  29. data/ext/ruby_carray.c +8 -1
  30. data/ext/ruby_ccomplex.c +1 -1
  31. data/ext/version.h +4 -4
  32. data/lib/carray.rb +7 -9
  33. data/lib/carray/autoload.rb +0 -2
  34. data/lib/carray/basic.rb +3 -5
  35. data/lib/carray/broadcast.rb +78 -22
  36. data/lib/carray/compose.rb +34 -10
  37. data/lib/carray/construct.rb +36 -14
  38. data/lib/carray/info.rb +1 -3
  39. data/lib/carray/inspect.rb +3 -5
  40. data/lib/carray/io/imagemagick.rb +1 -3
  41. data/lib/carray/iterator.rb +2 -3
  42. data/lib/carray/mask.rb +18 -7
  43. data/lib/carray/math.rb +4 -6
  44. data/lib/carray/math/histogram.rb +1 -3
  45. data/lib/carray/math/recurrence.rb +1 -3
  46. data/lib/carray/mkmf.rb +1 -3
  47. data/lib/carray/object/ca_obj_iterator.rb +1 -3
  48. data/lib/carray/object/ca_obj_link.rb +1 -3
  49. data/lib/carray/object/ca_obj_pack.rb +1 -3
  50. data/lib/carray/obsolete.rb +1 -17
  51. data/lib/carray/ordering.rb +1 -3
  52. data/lib/carray/serialize.rb +34 -25
  53. data/lib/carray/string.rb +1 -3
  54. data/lib/carray/struct.rb +3 -5
  55. data/lib/carray/testing.rb +5 -10
  56. data/lib/carray/time.rb +1 -3
  57. data/lib/carray/transform.rb +12 -3
  58. data/misc/NOTE +16 -38
  59. data/spec/Classes/CAUnboudRepeat_spec.rb +24 -0
  60. data/spec/Features/feature_attributes_spec.rb +6 -6
  61. data/spec/Features/feature_boolean_spec.rb +15 -14
  62. data/spec/Features/feature_broadcast.rb +16 -0
  63. data/spec/Features/feature_cast_spec.rb +1 -1
  64. data/spec/Features/feature_mask_spec.rb +6 -0
  65. metadata +10 -11
data/ext/carray.h CHANGED
@@ -13,6 +13,10 @@
13
13
 
14
14
  #include "ruby.h"
15
15
 
16
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
17
+ extern VALUE rb_cArithSeq;
18
+ #endif
19
+
16
20
  /* -------------------------------------------------------------------- */
17
21
 
18
22
  #include "carray_config.h"
data/ext/carray_access.c CHANGED
@@ -10,35 +10,10 @@
10
10
 
11
11
  #include "carray.h"
12
12
 
13
- #if RUBY_VERSION_CODE >= 240
14
- #define RSTRUCT_EMBED_LEN_MAX RSTRUCT_EMBED_LEN_MAX
15
- enum {
16
- RSTRUCT_EMBED_LEN_MAX = 3,
17
- RSTRUCT_ENUM_END
18
- };
19
- struct RStruct {
20
- struct RBasic basic;
21
- union {
22
- struct {
23
- long len;
24
- const VALUE *ptr;
25
- } heap;
26
- const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
27
- } as;
28
- };
29
- #define RSTRUCT(obj) (R_CAST(RStruct)(obj))
30
- #endif
31
-
32
- #if RUBY_VERSION_CODE >= 190
33
- #define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0])
34
- #define RANGE_END(r) (RSTRUCT(r)->as.ary[1])
35
- #define RANGE_EXCL(r) (RSTRUCT(r)->as.ary[2])
36
- #else
37
- static ID id_beg, id_end, id_excl;
38
- #define RANGE_BEG(r) (rb_ivar_get(r, id_beg))
39
- #define RANGE_END(r) (rb_ivar_get(r, id_end))
40
- #define RANGE_EXCL(r) (rb_ivar_get(r, id_excl))
41
- #endif
13
+ static ID id_begin, id_end, id_excl_end;
14
+ #define RANGE_BEG(r) (rb_funcall(r, id_begin, 0))
15
+ #define RANGE_END(r) (rb_funcall(r, id_end, 0))
16
+ #define RANGE_EXCL(r) (rb_funcall(r, id_excl_end, 0))
42
17
 
43
18
  static ID id_ca, id_to_ca;
44
19
  static VALUE sym_star, sym_perc;
@@ -614,17 +589,17 @@ rb_ca_scan_index (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
614
589
  info->ndim = ca_ndim;
615
590
  }
616
591
  else if ( rb_obj_is_kind_of(arg, rb_cRange) ) { /* ca[--,i..j,--] */
617
- ca_size_t first, last, excl, count, step;
592
+ ca_size_t start, last, excl, count, step;
618
593
  volatile VALUE iv_beg, iv_end, iv_excl;
619
594
  iv_beg = RANGE_BEG(arg);
620
595
  iv_end = RANGE_END(arg);
621
596
  iv_excl = RANGE_EXCL(arg);
622
597
  index_type[i] = CA_IDX_BLOCK; /* convert to block */
623
598
  if ( NIL_P(iv_beg) ) {
624
- first = 0;
599
+ start = 0;
625
600
  }
626
601
  else {
627
- first = NUM2SIZE(iv_beg);
602
+ start = NUM2SIZE(iv_beg);
628
603
  }
629
604
  if ( NIL_P(iv_end) ) {
630
605
  last = -1;
@@ -635,20 +610,20 @@ rb_ca_scan_index (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
635
610
  excl = RTEST(iv_excl);
636
611
 
637
612
  if ( info->range_check ) {
638
- CA_CHECK_INDEX_AT(first, ca_dim[i], i);
613
+ CA_CHECK_INDEX_AT(start, ca_dim[i], i);
639
614
  }
640
615
 
641
616
  if ( last < 0 ) { /* don't use CA_CHECK_INDEX for excl */
642
617
  last += ca_dim[i];
643
618
  }
644
- if ( excl && ( first == last ) ) {
645
- index[i].block.start = first;
619
+ if ( excl && ( start == last ) ) {
620
+ index[i].block.start = start;
646
621
  index[i].block.count = 0;
647
622
  index[i].block.step = 1;
648
623
  }
649
624
  else {
650
625
  if ( excl ) {
651
- last += ( (last>=first) ? -1 : 1 );
626
+ last += ( (last>=start) ? -1 : 1 );
652
627
  }
653
628
  if ( info->range_check ) {
654
629
  if ( last < 0 || last >= ca_dim[i] ) {
@@ -657,11 +632,71 @@ rb_ca_scan_index (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
657
632
  (ca_size_t) last, (ca_size_t) (ca_dim[i]-1), i);
658
633
  }
659
634
  }
660
- index[i].block.start = first;
661
- index[i].block.count = count = llabs(last - first) + 1;
662
- index[i].block.step = step = ( last >= first ) ? 1 : -1;
635
+ index[i].block.start = start;
636
+ index[i].block.count = count = llabs(last - start) + 1;
637
+ index[i].block.step = step = ( last >= start ) ? 1 : -1;
663
638
  }
664
639
  }
640
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
641
+ else if ( rb_obj_is_kind_of(arg, rb_cArithSeq) ) { /* ca[--,ArithSeq,--]*/
642
+ ca_size_t start, last, excl, count, step, bound;
643
+ volatile VALUE iv_beg, iv_end, iv_excl;
644
+ rb_arithmetic_sequence_components_t x;
645
+ rb_arithmetic_sequence_extract(arg, &x);
646
+ iv_beg = x.begin;
647
+ iv_end = x.end;
648
+ iv_excl = x.exclude_end;
649
+ step = NUM2SIZE(x.step);
650
+ if ( NIL_P(iv_beg) ) {
651
+ start = 0;
652
+ }
653
+ else {
654
+ start = NUM2SIZE(iv_beg);
655
+ }
656
+ if ( NIL_P(iv_end) ) {
657
+ last = -1;
658
+ }
659
+ else {
660
+ last = NUM2SIZE(iv_end);
661
+ }
662
+ excl = RTEST(iv_excl);
663
+ if ( step == 0 ) {
664
+ rb_raise(rb_eRuntimeError,
665
+ "step in index equals to 0 in block reference");
666
+ }
667
+ index_type[i] = CA_IDX_BLOCK;
668
+ CA_CHECK_INDEX_AT(start, ca_dim[i], i);
669
+ if ( last < 0 ) {
670
+ last += ca_dim[i];
671
+ }
672
+ if ( excl && ( start == last ) ) {
673
+ index[i].block.start = start;
674
+ index[i].block.count = 0;
675
+ index[i].block.step = 1;
676
+ }
677
+ else {
678
+ if ( excl ) {
679
+ last += ( (last>=start) ? -1 : 1 );
680
+ }
681
+ if ( last < 0 || last >= ca_dim[i] ) {
682
+ rb_raise(rb_eIndexError,
683
+ "index %lld is out of range (0..%lld) at %i-dim",
684
+ (ca_size_t) last, (ca_size_t) (ca_dim[i]-1), i);
685
+ }
686
+ if ( (last - start) * step < 0 ) {
687
+ count = 1;
688
+ }
689
+ else {
690
+ count = llabs(last - start)/llabs(step) + 1;
691
+ }
692
+ bound = start + (count - 1)*step;
693
+ CA_CHECK_INDEX_AT(bound, ca_dim[i], i);
694
+ index[i].block.start = start;
695
+ index[i].block.count = count;
696
+ index[i].block.step = step;
697
+ }
698
+ }
699
+ #endif
665
700
  else if ( TYPE(arg) == T_ARRAY ) { /* ca[--,[array],--] */
666
701
  if ( RARRAY_LEN(arg) == 1 ) {
667
702
  VALUE arg0 = rb_ary_entry(arg, 0);
@@ -1914,12 +1949,9 @@ void
1914
1949
  Init_carray_access ()
1915
1950
  {
1916
1951
 
1917
- #if RUBY_VERSION_CODE >= 190
1918
- #else
1919
- id_beg = rb_intern("begin");
1920
- id_end = rb_intern("end");
1921
- id_excl = rb_intern("excl");
1922
- #endif
1952
+ id_begin = rb_intern("begin");
1953
+ id_end = rb_intern("end");
1954
+ id_excl_end = rb_intern("exclude_end?");
1923
1955
 
1924
1956
  id_ca = rb_intern("ca");
1925
1957
  id_to_ca = rb_intern("to_ca");
@@ -17,7 +17,7 @@
17
17
  (Attribute)
18
18
  Returns the object type (e.g. CA_OBJ_ARRAY, CA_OBJ_BLOCK, ...).
19
19
  Since the object type can be known from the class of the object,
20
- this attribute method is rarely used.
20
+ this attribute methods is rarely used.
21
21
  */
22
22
 
23
23
  VALUE
@@ -711,6 +711,20 @@ rb_ca_data_type_import (VALUE self, VALUE data_type)
711
711
  return Qnil;
712
712
  }
713
713
 
714
+ static VALUE
715
+ rb_ca_set_data_class (VALUE self, VALUE klass)
716
+ {
717
+ if ( RTEST(rb_ca_is_fixlen_type(self)) &&
718
+ rb_obj_is_data_class(klass) ) {
719
+ rb_ivar_set(self, rb_intern("member"), rb_hash_new());
720
+ return rb_ivar_set(self, id_data_class, klass);
721
+ }
722
+ else {
723
+ rb_raise(rb_eTypeError, "invalid data_class or self is not fixlen array.");
724
+ }
725
+ return Qnil;
726
+ }
727
+
714
728
  /* ------------------------------------------------------------------- */
715
729
 
716
730
  CArray *
@@ -824,6 +838,7 @@ Init_carray_attribute ()
824
838
  rb_define_method(rb_cCArray, "parent", rb_ca_parent, 0);
825
839
 
826
840
  rb_define_method(rb_cCArray, "data_class", rb_ca_data_class, 0);
841
+ rb_define_method(rb_cCArray, "data_class=", rb_ca_set_data_class, 1);
827
842
 
828
843
  rb_define_method(rb_cCArray, "scalar?", rb_ca_is_scalar, 0);
829
844
 
data/ext/carray_cast.c CHANGED
@@ -66,7 +66,7 @@ OBJ2DBL (VALUE val)
66
66
  else if ( ! strncasecmp("-infinity", str, 9) ) {
67
67
  return -1.0/0.0;
68
68
  }
69
- return NUM2DBL(rb_Float(val));
69
+ return rb_cstr_to_dbl(str, 0);
70
70
  }
71
71
  default:
72
72
  return NUM2DBL(rb_Float(val));
@@ -342,6 +342,8 @@ rb_ca_format (int argc, VALUE *argv, VALUE self)
342
342
 
343
343
  #include <time.h>
344
344
 
345
+ #ifdef HAVE_STRPTIME
346
+
345
347
  /* @overload str_strptime (fmt)
346
348
 
347
349
  (Conversion)
@@ -404,7 +406,9 @@ rb_ca_strptime (VALUE self, VALUE rfmt)
404
406
  return obj;
405
407
  }
406
408
 
407
- /* @overload time_strptime (fmt)
409
+ #endif
410
+
411
+ /* @overload time_strftime (fmt)
408
412
 
409
413
  (Conversion)
410
414
  Creates object type array consist of strings
@@ -498,7 +502,10 @@ Init_carray_conversion ()
498
502
 
499
503
  rb_define_method(rb_cCArray, "str_format", rb_ca_format, -1);
500
504
 
505
+ #ifdef HAVE_STRPTIME
501
506
  rb_define_method(rb_cCArray, "str_strptime", rb_ca_strptime, 1);
507
+ #endif
508
+
502
509
  rb_define_method(rb_cCArray, "time_strftime", rb_ca_strftime, 1);
503
510
 
504
511
  rb_define_method(rb_cCArray, "test_ca_to_cptr", rb_test_ca_to_cptr, 0);
data/ext/carray_core.c CHANGED
@@ -1186,7 +1186,7 @@ rb_ca_data_class_encode (VALUE self, VALUE obj)
1186
1186
  VALUE
1187
1187
  rb_ca_members (VALUE self)
1188
1188
  {
1189
- VALUE data_class = rb_ca_data_class(self);
1189
+ volatile VALUE data_class = rb_ca_data_class(self);
1190
1190
  if ( NIL_P(data_class) ) {
1191
1191
  rb_raise(rb_eRuntimeError, "carray doesn't have data class");
1192
1192
  }
@@ -1198,9 +1198,9 @@ rb_ca_members (VALUE self)
1198
1198
  VALUE
1199
1199
  rb_ca_field_as_member (VALUE self, VALUE sym)
1200
1200
  {
1201
- VALUE data_class = rb_ca_data_class(self);
1202
- VALUE member;
1203
- VALUE obj;
1201
+ volatile VALUE data_class = rb_ca_data_class(self);
1202
+ volatile VALUE member;
1203
+ volatile VALUE obj;
1204
1204
 
1205
1205
  if ( NIL_P(data_class) ) {
1206
1206
  rb_raise(rb_eRuntimeError, "carray doesn't have data class");
@@ -1214,23 +1214,29 @@ rb_ca_field_as_member (VALUE self, VALUE sym)
1214
1214
  "for data_class array");
1215
1215
  }
1216
1216
 
1217
- if ( TYPE(sym) == T_SYMBOL ) {
1218
- sym = rb_funcall(sym, rb_intern("to_s"), 0);
1219
- }
1220
- else if ( rb_obj_is_kind_of(sym, rb_cInteger) ) {
1221
- VALUE member_names = rb_const_get(data_class, rb_intern("MEMBERS"));
1222
- sym = rb_ary_entry(member_names, NUM2SIZE(sym));
1217
+ if ( rb_obj_is_kind_of(sym, rb_cInteger) ) {
1218
+ volatile VALUE member_names = rb_const_get(data_class, rb_intern("MEMBERS"));
1219
+ sym = rb_ary_entry(member_names, NUM2SIZE(sym));
1220
+ obj = rb_hash_aref(member, sym);
1221
+ }
1222
+ else {
1223
+ obj = rb_hash_aref(member, sym);
1224
+ if ( NIL_P(obj) ) {
1225
+ sym = rb_funcall(sym, rb_intern("to_s"), 0);
1226
+ obj = rb_hash_aref(member, sym);
1227
+ }
1223
1228
  }
1224
1229
 
1225
- obj = rb_hash_aref(member, sym);
1226
-
1227
1230
  if ( rb_obj_is_carray(obj) ) {
1228
1231
  return obj;
1229
1232
  }
1230
1233
  else {
1231
- VALUE MEMBER_TABLE = rb_const_get(data_class, rb_intern("MEMBER_TABLE"));
1232
- VALUE info = rb_hash_aref(MEMBER_TABLE, sym);
1234
+ volatile VALUE MEMBER_TABLE = rb_const_get(data_class, rb_intern("MEMBER_TABLE"));
1235
+ volatile VALUE info = rb_hash_aref(MEMBER_TABLE, sym);
1233
1236
  if ( NIL_P(info) ) {
1237
+ if ( TYPE(sym) != T_STRING ) {
1238
+ sym = rb_funcall(sym, rb_intern("to_s"), 0);
1239
+ }
1234
1240
  rb_raise(rb_eRuntimeError,
1235
1241
  "can't find data_member named <%s>", StringValuePtr(sym));
1236
1242
  }
@@ -1249,7 +1255,7 @@ rb_ca_field_as_member (VALUE self, VALUE sym)
1249
1255
  VALUE
1250
1256
  rb_ca_fields (VALUE self)
1251
1257
  {
1252
- VALUE data_class = rb_ca_data_class(self);
1258
+ volatile VALUE data_class = rb_ca_data_class(self);
1253
1259
  volatile VALUE member_names, list;
1254
1260
  int i;
1255
1261
  if ( NIL_P(data_class) ) {
@@ -1272,7 +1278,7 @@ Returns an array of data class members (fields) with names specified
1272
1278
  VALUE
1273
1279
  rb_ca_fields_at (int argc, VALUE *argv, VALUE self)
1274
1280
  {
1275
- VALUE data_class = rb_ca_data_class(self);
1281
+ volatile VALUE data_class = rb_ca_data_class(self);
1276
1282
  volatile VALUE member_names, list;
1277
1283
  int i;
1278
1284
  if ( NIL_P(data_class) ) {
@@ -62,15 +62,15 @@ Returns the 1d index array for non-zero elements of self
62
62
  VALUE
63
63
  rb_ca_where (VALUE self)
64
64
  {
65
- volatile VALUE bool, obj;
65
+ volatile VALUE bool0, obj;
66
66
  CArray *ca, *co;
67
67
  boolean8_t *p, *m;
68
68
  ca_size_t *q;
69
69
  ca_size_t i, count;
70
70
 
71
- bool = ( ! rb_ca_is_boolean_type(self) ) ? rb_ca_to_boolean(self) : self;
71
+ bool0 = ( ! rb_ca_is_boolean_type(self) ) ? rb_ca_to_boolean(self) : self;
72
72
 
73
- Data_Get_Struct(bool, CArray, ca);
73
+ Data_Get_Struct(bool0, CArray, ca);
74
74
 
75
75
  ca_attach(ca);
76
76
 
data/ext/carray_mask.c CHANGED
@@ -757,7 +757,12 @@ rb_ca_is_masked (VALUE self)
757
757
 
758
758
  Data_Get_Struct(self, CArray, ca);
759
759
 
760
- co = carray_new(CA_BOOLEAN, ca->ndim, ca->dim, ca->bytes, NULL);
760
+ if ( ca_is_scalar(ca) ) {
761
+ co = cscalar_new(CA_BOOLEAN, ca->bytes, NULL);
762
+ }
763
+ else {
764
+ co = carray_new(CA_BOOLEAN, ca->ndim, ca->dim, ca->bytes, NULL);
765
+ }
761
766
 
762
767
  ca_update_mask(ca);
763
768
  if ( ! ca->mask ) {
@@ -798,7 +803,12 @@ rb_ca_is_not_masked (VALUE self)
798
803
 
799
804
  Data_Get_Struct(self, CArray, ca);
800
805
 
801
- co = carray_new(CA_BOOLEAN, ca->ndim, ca->dim, ca->bytes, NULL);
806
+ if ( ca_is_scalar(ca) ) {
807
+ co = cscalar_new(CA_BOOLEAN, ca->bytes, NULL);
808
+ }
809
+ else {
810
+ co = carray_new(CA_BOOLEAN, ca->ndim, ca->dim, ca->bytes, NULL);
811
+ }
802
812
 
803
813
  ca_update_mask(ca);
804
814
  if ( ! ca->mask ) {
data/ext/carray_math.rb CHANGED
@@ -155,6 +155,10 @@ monfunc("exp", "exp",
155
155
  FLOAT_TYPES => "(#2) = exp(#1);",
156
156
  CMPLX_TYPES => HAVE_COMPLEX ? "(#2) = cexp(#1);" : nil,
157
157
  OBJ_TYPES => '(#2) = rb_funcall((#1), rb_intern("exp"), 0);')
158
+ monfunc("exp2", "exp2",
159
+ FLOAT_TYPES => "(#2) = exp2(#1);",
160
+ CMPLX_TYPES => HAVE_COMPLEX ? "(#2) = cpow(2, (#1));" : nil,
161
+ OBJ_TYPES => '(#2) = rb_funcall((#1), rb_intern("exp2"), 0);')
158
162
  monfunc("exp10", "exp10",
159
163
  FLOAT_TYPES => "(#2) = pow(10, (#1));",
160
164
  CMPLX_TYPES => HAVE_COMPLEX ? "(#2) = cpow(10, (#1));" : nil,
@@ -166,6 +170,12 @@ monfunc("log", "log",
166
170
  monfunc("log10", "log10",
167
171
  FLOAT_TYPES => "(#2) = log10(#1);",
168
172
  OBJ_TYPES => '(#2) = rb_funcall((#1), rb_intern("log10"), 0);')
173
+ monfunc("log2", "log2",
174
+ FLOAT_TYPES => "(#2) = log2(#1);",
175
+ OBJ_TYPES => '(#2) = rb_funcall((#1), rb_intern("log2"), 0);')
176
+ monfunc("logb", "logb",
177
+ FLOAT_TYPES => "(#2) = logb(#1);",
178
+ OBJ_TYPES => '(#2) = rb_funcall((#1), rb_intern("logb"), 0);')
169
179
  monfunc("sin", "sin",
170
180
  FLOAT_TYPES => "(#2) = sin(#1);",
171
181
  CMPLX_TYPES => HAVE_COMPLEX ? "(#2) = csin(#1);" : nil,
@@ -217,12 +227,14 @@ monfunc("atanh", "atanh",
217
227
 
218
228
 
219
229
  binop("pmax", "pmax",
220
- ALL_TYPES =>"(#3) = (#1) > (#2) ? (#1) : (#2);",
230
+ INT_TYPES =>"(#3) = (#1) > (#2) ? (#1) : (#2);",
231
+ FLOAT_TYPES =>"(#3) = fmax(#1, #2);",
221
232
  CMPLX_TYPES => nil,
222
233
  OBJ_TYPES =>'(#3) = rb_funcall(rb_assoc_new((#1),(#2)), rb_intern("max"), 0);')
223
234
 
224
235
  binop("pmin", "pmin",
225
- ALL_TYPES =>"(#3) = (#1) < (#2) ? (#1) : (#2);",
236
+ INT_TYPES =>"(#3) = (#1) < (#2) ? (#1) : (#2);",
237
+ FLOAT_TYPES =>"(#3) = fmin(#1, #2);",
226
238
  CMPLX_TYPES => nil,
227
239
  OBJ_TYPES =>'(#3) = rb_funcall(rb_assoc_new((#1),(#2)), rb_intern("min"), 0);')
228
240
 
@@ -258,6 +270,12 @@ binop("rcp_mul", "rcp_mul",
258
270
 
259
271
  binop("%", "mod",
260
272
  INT_TYPES => "if ((#2)==0) {ca_zerodiv();}; (#3) = (#1) % (#2);",
273
+ FLOAT_TYPES => "(#3) = fmod(#1, #2);",
274
+ OBJ_TYPES => '(#3) = rb_funcall((#1), id_percent, 1, (#2));')
275
+
276
+ binop("reminder", "reminder",
277
+ INT_TYPES => "if ((#2)==0) {ca_zerodiv();}; (#3) = (#1) % (#2);",
278
+ FLOAT_TYPES => "(#3) = remainder(#1, #2);",
261
279
  OBJ_TYPES => '(#3) = rb_funcall((#1), id_percent, 1, (#2));')
262
280
 
263
281
  binop("&", "bit_and_i",
data/ext/carray_numeric.c CHANGED
@@ -11,11 +11,6 @@
11
11
  #include "ruby.h"
12
12
  #include "carray.h"
13
13
 
14
- #if RUBY_VERSION_CODE >= 240
15
- # define rb_cFixnum rb_cInteger
16
- # define rb_cBignum rb_cInteger
17
- #endif
18
-
19
14
  VALUE CA_NAN, CA_INF;
20
15
 
21
16
  static ID id___or__;
@@ -24,24 +19,18 @@ static ID id___xor__;
24
19
  static ID id___rshift__;
25
20
  static ID id___lshift__;
26
21
 
27
- VALUE
28
- rb_num_nan (VALUE self)
29
- {
30
- return CA_NAN;
31
- }
32
-
33
- VALUE
34
- rb_num_inf (VALUE self)
35
- {
36
- return CA_INF;
37
- }
22
+ static ID id_bit_or;
23
+ static ID id_bit_and;
24
+ static ID id_bit_xor;
25
+ static ID id_lshift;
26
+ static ID id_rshift;
38
27
 
39
28
  static VALUE
40
29
  rb_hack_or(VALUE x, VALUE y)
41
30
  {
42
31
  if ( rb_obj_is_carray(y) ) {
43
32
  if ( rb_ca_is_boolean_type(y) ) {
44
- return rb_funcall(y, rb_intern("bit_or"), 1, x);
33
+ return rb_funcall(y, id_bit_or, 1, x);
45
34
  }
46
35
  else {
47
36
  #if RUBY_VERSION_CODE >= 190
@@ -61,7 +50,7 @@ rb_hack_and (VALUE x, VALUE y)
61
50
  {
62
51
  if ( rb_obj_is_carray(y) ) {
63
52
  if ( rb_ca_is_boolean_type(y) ) {
64
- return rb_funcall(y, rb_intern("bit_and"), 1, x);
53
+ return rb_funcall(y, id_bit_and, 1, x);
65
54
  }
66
55
  else {
67
56
  #if RUBY_VERSION_CODE >= 190
@@ -81,7 +70,7 @@ rb_hack_xor (VALUE x, VALUE y)
81
70
  {
82
71
  if ( rb_obj_is_carray(y) ) {
83
72
  if ( rb_ca_is_boolean_type(y) ) {
84
- return rb_funcall(y, rb_intern("bit_xor"), 1, x);
73
+ return rb_funcall(y, id_bit_xor, 1, x);
85
74
  }
86
75
  else {
87
76
  #if RUBY_VERSION_CODE >= 190
@@ -101,7 +90,7 @@ rb_hack_lshift (VALUE x, VALUE y)
101
90
  {
102
91
  if ( rb_obj_is_carray(y) ) {
103
92
  #if RUBY_VERSION_CODE >= 190
104
- return rb_num_coerce_bin(x, y, rb_intern("<<"));
93
+ return rb_num_coerce_bin(x, y, id_lshift);
105
94
  #else
106
95
  return rb_num_coerce_bin(x, y);
107
96
  #endif
@@ -116,7 +105,7 @@ rb_hack_rshift (VALUE x, VALUE y)
116
105
  {
117
106
  if ( rb_obj_is_carray(y) ) {
118
107
  #if RUBY_VERSION_CODE >= 190
119
- return rb_num_coerce_bin(x, y, rb_intern(">>"));
108
+ return rb_num_coerce_bin(x, y, id_rshift);
120
109
  #else
121
110
  return rb_num_coerce_bin(x, y);
122
111
  #endif
@@ -126,12 +115,6 @@ rb_hack_rshift (VALUE x, VALUE y)
126
115
  }
127
116
  }
128
117
 
129
- static VALUE
130
- rb_hack_star (VALUE x, VALUE y)
131
- {
132
- return rb_funcall(y, rb_intern("*"), 1, x);
133
- }
134
-
135
118
  /* ------------------------------------------------------------------- */
136
119
 
137
120
  #ifdef HAVE_COMPLEX_H
@@ -197,35 +180,51 @@ Init_carray_numeric ()
197
180
  {
198
181
  /* hack Fixnum and Bignum's "|", "&", "^", "<<", ">>" */
199
182
 
200
- id___or__ = rb_intern("__or__");
201
- id___and__ = rb_intern("__and__");
202
- id___xor__ = rb_intern("__xor__");
183
+ id___or__ = rb_intern("__or__");
184
+ id___and__ = rb_intern("__and__");
185
+ id___xor__ = rb_intern("__xor__");
203
186
  id___rshift__ = rb_intern("__rshift__");
204
187
  id___lshift__ = rb_intern("__lshift__");
205
188
 
189
+ id_bit_or = rb_intern("bit_or");
190
+ id_bit_and = rb_intern("bit_and");
191
+ id_bit_xor = rb_intern("bit_xor");
192
+ id_lshift = rb_intern("<<");
193
+ id_rshift = rb_intern(">>");
194
+
206
195
  CA_NAN = rb_float_new(0.0/0.0);
207
196
  CA_INF = rb_float_new(1.0/0.0);
208
197
  rb_define_const(rb_cObject, "CA_NAN", CA_NAN);
209
198
  rb_define_const(rb_cObject, "CA_INF", CA_INF);
210
- rb_define_global_function("nan", rb_num_nan, 0);
211
- rb_define_global_function("inf", rb_num_inf, 0);
212
199
 
213
200
  rb_define_alias(rb_cTrueClass, "__or__", "|");
214
201
  rb_define_alias(rb_cTrueClass, "__and__", "&");
215
202
  rb_define_alias(rb_cTrueClass, "__xor__", "^");
216
203
 
204
+ rb_define_method(rb_cTrueClass, "|", rb_hack_or, 1);
205
+ rb_define_method(rb_cTrueClass, "&", rb_hack_and, 1);
206
+ rb_define_method(rb_cTrueClass, "^", rb_hack_xor, 1);
207
+
217
208
  rb_define_alias(rb_cFalseClass, "__or__", "|");
218
209
  rb_define_alias(rb_cFalseClass, "__and__", "&");
219
210
  rb_define_alias(rb_cFalseClass, "__xor__", "^");
220
211
 
221
- #if RUBY_VERSION_CODE >= 240
212
+ rb_define_method(rb_cFalseClass, "|", rb_hack_or, 1);
213
+ rb_define_method(rb_cFalseClass, "&", rb_hack_and, 1);
214
+ rb_define_method(rb_cFalseClass, "^", rb_hack_xor, 1);
222
215
 
216
+ #if RUBY_VERSION_CODE >= 240
223
217
  rb_define_alias(rb_cInteger, "__or__", "|");
224
218
  rb_define_alias(rb_cInteger, "__and__", "&");
225
219
  rb_define_alias(rb_cInteger, "__xor__", "^");
226
220
  rb_define_alias(rb_cInteger, "__lshift__", "<<");
227
221
  rb_define_alias(rb_cInteger, "__rshift__", ">>");
228
222
 
223
+ rb_define_method(rb_cInteger, "|", rb_hack_or, 1);
224
+ rb_define_method(rb_cInteger, "&", rb_hack_and, 1);
225
+ rb_define_method(rb_cInteger, "^", rb_hack_xor, 1);
226
+ rb_define_method(rb_cInteger, "<<", rb_hack_lshift, 1);
227
+ rb_define_method(rb_cInteger, ">>", rb_hack_rshift, 1);
229
228
  #else
230
229
  rb_define_alias(rb_cFixnum, "__or__", "|");
231
230
  rb_define_alias(rb_cFixnum, "__and__", "&");
@@ -238,25 +237,7 @@ Init_carray_numeric ()
238
237
  rb_define_alias(rb_cBignum, "__xor__", "^");
239
238
  rb_define_alias(rb_cBignum, "__lshift__", "<<");
240
239
  rb_define_alias(rb_cBignum, "__rshift__", ">>");
241
- #endif
242
240
 
243
- rb_define_method(rb_cTrueClass, "|", rb_hack_or, 1);
244
- rb_define_method(rb_cTrueClass, "&", rb_hack_and, 1);
245
- rb_define_method(rb_cTrueClass, "^", rb_hack_xor, 1);
246
- rb_define_method(rb_cTrueClass, "*", rb_hack_star, 1);
247
-
248
- rb_define_method(rb_cFalseClass, "|", rb_hack_or, 1);
249
- rb_define_method(rb_cFalseClass, "&", rb_hack_and, 1);
250
- rb_define_method(rb_cFalseClass, "^", rb_hack_xor, 1);
251
- rb_define_method(rb_cFalseClass, "*", rb_hack_star, 1);
252
-
253
- #if RUBY_VERSION_CODE >= 240
254
- rb_define_method(rb_cInteger, "|", rb_hack_or, 1);
255
- rb_define_method(rb_cInteger, "&", rb_hack_and, 1);
256
- rb_define_method(rb_cInteger, "^", rb_hack_xor, 1);
257
- rb_define_method(rb_cInteger, "<<", rb_hack_lshift, 1);
258
- rb_define_method(rb_cInteger, ">>", rb_hack_rshift, 1);
259
- #else
260
241
  rb_define_method(rb_cFixnum, "|", rb_hack_or, 1);
261
242
  rb_define_method(rb_cFixnum, "&", rb_hack_and, 1);
262
243
  rb_define_method(rb_cFixnum, "^", rb_hack_xor, 1);