carray 3.0.3 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +469 -0
  3. data/README.md +3 -2
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_descriptor.h +27 -24
  7. data/ext/ca_axis_dispatch.c +14 -26
  8. data/ext/ca_axis_group.c +27 -27
  9. data/ext/ca_binop_dispatch.c +1 -29
  10. data/ext/ca_binop_dispatch.h +0 -1
  11. data/ext/ca_categorical_iterator.c +231 -153
  12. data/ext/ca_compare.c +9 -20
  13. data/ext/ca_composite_dispatch.c +9 -9
  14. data/ext/ca_group_iter.c +16 -17
  15. data/ext/ca_kernel_iterator.c +1240 -2000
  16. data/ext/ca_kernel_iterator.h +502 -519
  17. data/ext/ca_monop_dispatch.c +82 -59
  18. data/ext/ca_monop_dispatch.h +1 -0
  19. data/ext/ca_obj_array.c +152 -45
  20. data/ext/ca_obj_bincmp.c +25 -21
  21. data/ext/ca_obj_binop.c +16 -26
  22. data/ext/ca_obj_bitarray.c +8 -3
  23. data/ext/ca_obj_bitfield.c +63 -49
  24. data/ext/ca_obj_block.c +18 -9
  25. data/ext/ca_obj_byte_swap.c +7 -7
  26. data/ext/ca_obj_const_string.c +188 -22
  27. data/ext/ca_obj_face.c +280 -58
  28. data/ext/ca_obj_face.h +19 -0
  29. data/ext/ca_obj_fake.c +15 -29
  30. data/ext/ca_obj_farray.c +6 -3
  31. data/ext/ca_obj_field.c +30 -8
  32. data/ext/ca_obj_fixlen_string.c +2 -3
  33. data/ext/ca_obj_grid.c +455 -134
  34. data/ext/ca_obj_meld.c +172 -34
  35. data/ext/ca_obj_moncmp.c +23 -8
  36. data/ext/ca_obj_monop.c +113 -67
  37. data/ext/ca_obj_object.c +210 -52
  38. data/ext/ca_obj_record.c +15 -7
  39. data/ext/ca_obj_reduce.c +17 -8
  40. data/ext/ca_obj_refer.c +42 -35
  41. data/ext/ca_obj_remap.c +30 -9
  42. data/ext/ca_obj_repeat.c +9 -10
  43. data/ext/ca_obj_roll.c +31 -10
  44. data/ext/ca_obj_select.c +48 -14
  45. data/ext/ca_obj_select_axis.c +15 -47
  46. data/ext/ca_obj_shift.c +41 -7
  47. data/ext/ca_obj_stack.c +180 -34
  48. data/ext/ca_obj_stride.c +190 -134
  49. data/ext/ca_obj_string.c +80 -4
  50. data/ext/ca_obj_tile.c +32 -11
  51. data/ext/ca_obj_time.c +22 -6
  52. data/ext/ca_obj_timedelta.c +22 -6
  53. data/ext/ca_obj_transpose.c +13 -7
  54. data/ext/ca_obj_triop.c +26 -32
  55. data/ext/ca_obj_window.c +267 -74
  56. data/ext/ca_op_ipower.c +4 -4
  57. data/ext/ca_sort_kernels.h +6 -3
  58. data/ext/ca_sweep_engine.c +2 -2
  59. data/ext/caframe_csv_reader.c +80 -1
  60. data/ext/carray.h +214 -75
  61. data/ext/carray_access.c +200 -99
  62. data/ext/carray_address_basis.c +343 -87
  63. data/ext/carray_attribute.c +113 -6
  64. data/ext/carray_bincount.c +10 -8
  65. data/ext/carray_broadcast.c +13 -8
  66. data/ext/carray_build_flags.h +3 -0
  67. data/ext/carray_call_cfunc.c +108 -0
  68. data/ext/carray_cast.c +375 -96
  69. data/ext/carray_cast_func.rb +90 -20
  70. data/ext/carray_class.c +4 -3
  71. data/ext/carray_config.h +28 -0
  72. data/ext/carray_conversion.c +18 -9
  73. data/ext/carray_copy.c +51 -14
  74. data/ext/carray_core.c +150 -55
  75. data/ext/carray_count.c +56 -20
  76. data/ext/carray_element.c +81 -33
  77. data/ext/carray_factorize.c +138 -84
  78. data/ext/carray_generate.c +199 -52
  79. data/ext/carray_histogram.c +63 -18
  80. data/ext/carray_hold.c +12 -15
  81. data/ext/carray_index_classifier.c +388 -176
  82. data/ext/carray_internal.h +348 -29
  83. data/ext/carray_kernels_bincmp.c +4453 -0
  84. data/ext/carray_kernels_binop.c +11368 -0
  85. data/ext/carray_kernels_init.c +1734 -0
  86. data/ext/carray_kernels_moncmp.c +2104 -0
  87. data/ext/carray_kernels_monop.c +18369 -0
  88. data/ext/carray_kernels_reduce_aggregate.c +23818 -0
  89. data/ext/carray_kernels_reduce_boolean.c +406 -0
  90. data/ext/carray_kernels_reduce_cumulative.c +10086 -0
  91. data/ext/carray_kernels_reduce_extreme.c +17634 -0
  92. data/ext/carray_kernels_reduce_variance.c +3849 -0
  93. data/ext/carray_kernels_scan.c +4302 -0
  94. data/ext/carray_kernels_search.c +33829 -0
  95. data/ext/carray_kernels_sort.c +10897 -0
  96. data/ext/carray_kernels_triop.c +1864 -0
  97. data/ext/carray_key_windows.c +220 -0
  98. data/ext/carray_lazy.c +170 -111
  99. data/ext/carray_mask.c +337 -94
  100. data/ext/carray_median_percentile.c +82 -28
  101. data/ext/carray_memory_view.c +669 -561
  102. data/ext/carray_operator.c +129 -52
  103. data/ext/carray_order.c +604 -77
  104. data/ext/carray_partition.c +28 -27
  105. data/ext/carray_random.c +85 -31
  106. data/ext/carray_round.c +273 -0
  107. data/ext/carray_scatter.c +87 -45
  108. data/ext/carray_segment.c +3 -3
  109. data/ext/carray_slab.c +123 -37
  110. data/ext/carray_sort.c +259 -51
  111. data/ext/carray_sort_kernel.c +5 -7
  112. data/ext/carray_struct.c +54 -61
  113. data/ext/carray_test.c +26 -5
  114. data/ext/carray_time_text.c +4 -2
  115. data/ext/carray_undef.c +4 -0
  116. data/ext/carray_utils.c +309 -66
  117. data/ext/mk_call_cfunc.rb +19 -2
  118. data/ext/mkkernel.rb +403 -350
  119. data/ext/ruby_carray.c +10 -4
  120. data/ext/version.h +4 -4
  121. data/lib/carray/attribute.rb +139 -22
  122. data/lib/carray/autoload_carray.rb +8 -31
  123. data/lib/carray/autoload_method_extension.rb +14 -5
  124. data/lib/carray/axis_group.rb +255 -106
  125. data/lib/carray/basics.rb +105 -17
  126. data/lib/carray/bincount_nd.rb +12 -2
  127. data/lib/carray/block_iterator.rb +126 -23
  128. data/lib/carray/boolean_reduce.rb +17 -17
  129. data/lib/carray/categorical.rb +195 -59
  130. data/lib/carray/categorical_iterator.rb +132 -29
  131. data/lib/carray/complex.rb +5 -5
  132. data/lib/carray/conditional.rb +67 -18
  133. data/lib/carray/const_string.rb +24 -5
  134. data/lib/carray/construct.rb +15 -11
  135. data/lib/carray/data_type_extension.rb +9 -1
  136. data/lib/carray/distance_limit.rb +77 -0
  137. data/lib/carray/fixlen_string.rb +48 -3
  138. data/lib/carray/frame/column_verbs.rb +71 -0
  139. data/lib/carray/frame/concat.rb +17 -3
  140. data/lib/carray/frame/convert.rb +69 -0
  141. data/lib/carray/frame/csv_parser.rb +111 -17
  142. data/lib/carray/frame/describe.rb +3 -2
  143. data/lib/carray/frame/frame.rb +252 -28
  144. data/lib/carray/frame/group.rb +603 -101
  145. data/lib/carray/frame/io.rb +117 -28
  146. data/lib/carray/frame/join.rb +312 -51
  147. data/lib/carray/frame/records.rb +83 -7
  148. data/lib/carray/frame/reshape.rb +42 -35
  149. data/lib/carray/frame/sort.rb +7 -19
  150. data/lib/carray/frame/verbs.rb +188 -48
  151. data/lib/carray/frame/windows.rb +117 -0
  152. data/lib/carray/frame.rb +2 -0
  153. data/lib/carray/fuse_source.rb +42 -6
  154. data/lib/carray/fusion.rb +40 -16
  155. data/lib/carray/histogram.rb +6 -1
  156. data/lib/carray/inspect.rb +31 -8
  157. data/lib/carray/iterator.rb +85 -7
  158. data/lib/carray/key_windows.rb +620 -0
  159. data/lib/carray/lazy.rb +217 -183
  160. data/lib/carray/mask_gap_fill.rb +63 -57
  161. data/lib/carray/meld_reduce.rb +12 -14
  162. data/lib/carray/methods/bin.rb +26 -18
  163. data/lib/carray/methods/bincount.rb +16 -0
  164. data/lib/carray/methods/bit_string.rb +1 -1
  165. data/lib/carray/methods/choose.rb +16 -3
  166. data/lib/carray/methods/composition.rb +3 -1
  167. data/lib/carray/methods/gather_nd.rb +14 -5
  168. data/lib/carray/methods/insert_block.rb +2 -2
  169. data/lib/carray/methods/is_between.rb +59 -0
  170. data/lib/carray/methods/is_in.rb +61 -37
  171. data/lib/carray/methods/join.rb +1 -6
  172. data/lib/carray/methods/lag.rb +49 -0
  173. data/lib/carray/methods/locate_addr.rb +47 -51
  174. data/lib/carray/methods/mode.rb +1 -1
  175. data/lib/carray/methods/nunique.rb +11 -6
  176. data/lib/carray/methods/resize.rb +3 -3
  177. data/lib/carray/methods/value_counts.rb +4 -11
  178. data/lib/carray/record_order.rb +3 -3
  179. data/lib/carray/rng.rb +3 -0
  180. data/lib/carray/runtime.rb +53 -8
  181. data/lib/carray/segment_iterator.rb +323 -88
  182. data/lib/carray/serialize.rb +45 -14
  183. data/lib/carray/slab_iterator.rb +50 -0
  184. data/lib/carray/stack.rb +15 -12
  185. data/lib/carray/string.rb +113 -5
  186. data/lib/carray/string_operation_extension.rb +21 -6
  187. data/lib/carray/struct.rb +9 -21
  188. data/lib/carray/struct_builder.rb +24 -11
  189. data/lib/carray/time.rb +819 -158
  190. data/lib/carray/window_iterator.rb +122 -16
  191. data/lib/carray.rb +7 -0
  192. data/yard-stubs/ca_obj_bitfield.rb +1 -1
  193. data/yard-stubs/ca_obj_field.rb +4 -0
  194. data/yard-stubs/ca_obj_grid.rb +21 -10
  195. data/yard-stubs/ca_obj_refer.rb +2 -1
  196. data/yard-stubs/ca_obj_roll.rb +2 -2
  197. data/yard-stubs/ca_obj_shift.rb +5 -1
  198. data/yard-stubs/ca_obj_tile.rb +1 -1
  199. data/yard-stubs/ca_obj_transpose.rb +5 -4
  200. data/yard-stubs/ca_obj_window.rb +8 -3
  201. data/yard-stubs/carray_access.rb +6 -1
  202. data/yard-stubs/carray_attribute.rb +3 -6
  203. data/yard-stubs/carray_cast.rb +12 -0
  204. data/yard-stubs/carray_conversion.rb +7 -2
  205. data/yard-stubs/carray_copy.rb +4 -2
  206. data/yard-stubs/carray_count.rb +4 -4
  207. data/yard-stubs/carray_element.rb +17 -10
  208. data/yard-stubs/carray_generate.rb +21 -1
  209. data/yard-stubs/carray_mask.rb +32 -3
  210. data/yard-stubs/carray_math.rb +41 -5
  211. data/yard-stubs/carray_median_percentile.rb +5 -2
  212. data/yard-stubs/carray_memory_view.rb +40 -23
  213. data/yard-stubs/carray_order.rb +129 -22
  214. data/yard-stubs/carray_random.rb +13 -4
  215. data/yard-stubs/carray_scatter.rb +17 -10
  216. data/yard-stubs/carray_slab.rb +9 -2
  217. data/yard-stubs/carray_sort.rb +6 -5
  218. data/yard-stubs/carray_test.rb +5 -3
  219. metadata +25 -3
  220. data/lib/carray/arrow_tensor.rb +0 -401
  221. data/lib/carray/table.rb +0 -108
data/ext/carray_element.c CHANGED
@@ -20,18 +20,40 @@
20
20
  #include "ca_obj_face.h"
21
21
  #include "carray_internal.h" /* ca_obj_extremum_replaces */
22
22
 
23
+ /* An element index is read as `[]` reads a key: an Integer, or a Float
24
+ with no fraction. */
25
+ static inline ca_size_t
26
+ elem_index_value (VALUE v)
27
+ {
28
+ ca_size_t k;
29
+ if ( FIXNUM_P(v) ) return (ca_size_t) FIX2LONG(v);
30
+ switch ( ca_index_key_position(v, &k) ) {
31
+ case 1:
32
+ return k;
33
+ case 2:
34
+ return CA_LENGTH_MAX; /* past int64: past every axis, refused as out of range */
35
+ default:
36
+ rb_raise(rb_eIndexError, "object '%"PRIsVALUE"' is invalid for an index",
37
+ rb_inspect(v));
38
+ }
39
+ }
40
+
23
41
  /* T_ARRAY index parser. ridx is assumed already known to be T_ARRAY.
24
42
  Direct VALUE * access + FIXNUM_P fast path eliminates rb_ary_entry
25
43
  bounds check and NUM2SIZE Bignum branching for the common case. */
26
44
  static inline void
27
45
  elem_parse_idx_array (CArray *ca, VALUE rary, ca_size_t *idx)
28
46
  {
29
- const VALUE *iarr = RARRAY_CONST_PTR(rary);
47
+ const VALUE *iarr;
30
48
  int8_t ndim = ca->ndim;
31
49
  int8_t i;
50
+ if ( RARRAY_LEN(rary) != ndim ) {
51
+ rb_raise(rb_eIndexError, "%ld indices given for a carray of ndim %i",
52
+ (long) RARRAY_LEN(rary), (int) ndim);
53
+ }
54
+ iarr = RARRAY_CONST_PTR(rary);
32
55
  for (i=0; i<ndim; i++) {
33
- VALUE v = iarr[i];
34
- ca_size_t k = FIXNUM_P(v) ? (ca_size_t)FIX2LONG(v) : NUM2SIZE(v);
56
+ ca_size_t k = elem_index_value(iarr[i]);
35
57
  CA_CHECK_INDEX(k, ca->dim[i]);
36
58
  idx[i] = k;
37
59
  }
@@ -41,7 +63,7 @@ elem_parse_idx_array (CArray *ca, VALUE rary, ca_size_t *idx)
41
63
  static inline ca_size_t
42
64
  elem_parse_idx_scalar (CArray *ca, VALUE ridx)
43
65
  {
44
- ca_size_t k = FIXNUM_P(ridx) ? (ca_size_t)FIX2LONG(ridx) : NUM2SIZE(ridx);
66
+ ca_size_t k = elem_index_value(ridx);
45
67
  CA_CHECK_INDEX(k, ca->elements);
46
68
  return k;
47
69
  }
@@ -278,33 +300,56 @@ rb_ca_elem_store (VALUE self, VALUE ridx, VALUE obj)
278
300
  if ( FIXNUM_P(obj) ) { *(int64_t *)p = (int64_t)FIX2LONG(obj); return obj; }
279
301
  break;
280
302
  case CA_INT32:
281
- if ( FIXNUM_P(obj) ) { *(int32_t *)p = (int32_t)FIX2LONG(obj); return obj; }
303
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= INT32_MIN && FIX2LONG(obj) <= INT32_MAX ) {
304
+ /* fits: checked against the type's range above */
305
+ *(int32_t *)p = (int32_t)FIX2LONG(obj); return obj;
306
+ }
282
307
  break;
283
308
  case CA_INT16:
284
- if ( FIXNUM_P(obj) ) { *(int16_t *)p = (int16_t)FIX2LONG(obj); return obj; }
309
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= INT16_MIN && FIX2LONG(obj) <= INT16_MAX ) {
310
+ /* fits: checked against the type's range above */
311
+ *(int16_t *)p = (int16_t)FIX2LONG(obj); return obj;
312
+ }
285
313
  break;
286
314
  case CA_INT8:
287
- if ( FIXNUM_P(obj) ) { *(int8_t *)p = (int8_t)FIX2LONG(obj); return obj; }
315
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= INT8_MIN && FIX2LONG(obj) <= INT8_MAX ) {
316
+ /* fits: checked against the type's range above */
317
+ *(int8_t *)p = (int8_t)FIX2LONG(obj); return obj;
318
+ }
288
319
  break;
289
320
  case CA_UINT64:
290
- if ( FIXNUM_P(obj) ) { *(uint64_t *)p = (uint64_t)FIX2LONG(obj); return obj; }
321
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= 0 ) {
322
+ *(uint64_t *)p = (uint64_t)FIX2LONG(obj); return obj;
323
+ }
291
324
  break;
292
325
  case CA_UINT32:
293
- if ( FIXNUM_P(obj) ) { *(uint32_t *)p = (uint32_t)FIX2LONG(obj); return obj; }
326
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= 0 && FIX2LONG(obj) <= (long) UINT32_MAX ) {
327
+ /* fits: checked against the type's range above */
328
+ *(uint32_t *)p = (uint32_t)FIX2LONG(obj); return obj;
329
+ }
294
330
  break;
295
331
  case CA_UINT16:
296
- if ( FIXNUM_P(obj) ) { *(uint16_t *)p = (uint16_t)FIX2LONG(obj); return obj; }
332
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= 0 && FIX2LONG(obj) <= (long) UINT16_MAX ) {
333
+ /* fits: checked against the type's range above */
334
+ *(uint16_t *)p = (uint16_t)FIX2LONG(obj); return obj;
335
+ }
297
336
  break;
298
337
  case CA_UINT8:
299
- if ( FIXNUM_P(obj) ) { *(uint8_t *)p = (uint8_t)FIX2LONG(obj); return obj; }
338
+ if ( FIXNUM_P(obj) && FIX2LONG(obj) >= 0 && FIX2LONG(obj) <= (long) UINT8_MAX ) {
339
+ /* fits: checked against the type's range above */
340
+ *(uint8_t *)p = (uint8_t)FIX2LONG(obj); return obj;
341
+ }
300
342
  break;
301
343
  case CA_BOOLEAN:
302
344
  if ( obj == Qtrue ) { *(uint8_t *)p = 1; return obj; }
303
345
  if ( obj == Qfalse ) { *(uint8_t *)p = 0; return obj; }
304
- if ( FIXNUM_P(obj) ) { *(uint8_t *)p = (FIX2LONG(obj) != 0); return obj; }
346
+ if ( obj == INT2FIX(0) || obj == INT2FIX(1) ) {
347
+ *(uint8_t *)p = (obj == INT2FIX(1)); return obj;
348
+ }
305
349
  break;
306
350
  }
307
- /* Fall through: data type matches but obj kind needs general coercion. */
351
+ /* Fall through: the value needs the general coercion, or does not fit
352
+ the cell, which the general path refuses. */
308
353
  }
309
354
  }
310
355
 
@@ -331,14 +376,12 @@ rb_ca_elem_fetch (VALUE self, VALUE ridx)
331
376
 
332
377
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
333
378
 
334
- if ( ca_is_empty(ca) ) return Qnil;
335
-
336
379
  if ( TYPE(ridx) == T_ARRAY ) {
337
380
  volatile VALUE out;
338
381
  elem_parse_idx_array(ca, ridx, idx);
339
382
 
340
383
  /* Super-hot path: entity + common numeric data type + no mask.
341
- Bypass ca_fetch_index dispatch AND rb_ca_ptr2obj cast-table dispatch.
384
+ Bypass ca_fetch_index dispatch AND rb_ca_ptr2obj_storage cast-table dispatch.
342
385
  Covers the bench's float64 / int64 / int32 cases. */
343
386
  if ( ca_is_entity(ca) && ! ca->mask ) {
344
387
  ca_size_t addr = elem_entity_addr(ca, idx);
@@ -370,13 +413,13 @@ rb_ca_elem_fetch (VALUE self, VALUE ridx)
370
413
  else {
371
414
  ca_fetch_index(ca, idx, v);
372
415
  }
373
- out = rb_ca_ptr2obj(self, v);
416
+ out = rb_ca_ptr2obj_storage(self, v);
374
417
  }
375
418
  else {
376
419
  volatile VALUE holder;
377
420
  char *v = ALLOCV_N(char, holder, ca->bytes);
378
421
  ca_fetch_index(ca, idx, v);
379
- out = rb_ca_ptr2obj(self, v);
422
+ out = rb_ca_ptr2obj_storage(self, v);
380
423
  ALLOCV_END(holder);
381
424
  }
382
425
 
@@ -749,6 +792,11 @@ rb_ca_elem_unmask (VALUE self, VALUE ridx)
749
792
  * rule (NaN is treated as missing: `min(NaN, v)` returns `v`,
750
793
  * `min(x, NaN)` returns `x`). Raises for non-numeric data_type. */
751
794
 
795
+ /* The entity fast path takes a Float into a float cell and an Integer
796
+ that fits the cell. Anything else -- a Float into an integer cell, an
797
+ Integer out of the type's range, a Bignum or Rational -- goes to the
798
+ general path, which compares in Ruby and stores as `self[idx] = v`
799
+ does, so a value that wins but does not fit raises. */
752
800
  #define ELEM_MINMAX_BODY(OP) do { \
753
801
  if ( ca_is_entity(ca) ) { \
754
802
  ca_size_t addr; \
@@ -766,14 +814,6 @@ rb_ca_elem_unmask (VALUE self, VALUE ridx)
766
814
  switch ( ca->data_type ) { \
767
815
  case CA_FLOAT64: { double *q=(double *)p; if (v OP *q || *q != *q) *q = v; return self; } \
768
816
  case CA_FLOAT32: { float *q=(float *)p; float vf=(float)v; if (vf OP *q || *q != *q) *q = vf; return self; } \
769
- case CA_INT64: { int64_t *q=(int64_t *)p; if ((int64_t)v OP *q) *q = (int64_t)v; return self; } \
770
- case CA_INT32: { int32_t *q=(int32_t *)p; if ((int32_t)v OP *q) *q = (int32_t)v; return self; } \
771
- case CA_INT16: { int16_t *q=(int16_t *)p; if ((int16_t)v OP *q) *q = (int16_t)v; return self; } \
772
- case CA_INT8: { int8_t *q=(int8_t *)p; if ((int8_t )v OP *q) *q = (int8_t )v; return self; } \
773
- case CA_UINT64: { uint64_t *q=(uint64_t*)p; if ((uint64_t)v OP *q) *q = (uint64_t)v; return self; } \
774
- case CA_UINT32: { uint32_t *q=(uint32_t*)p; if ((uint32_t)v OP *q) *q = (uint32_t)v; return self; } \
775
- case CA_UINT16: { uint16_t *q=(uint16_t*)p; if ((uint16_t)v OP *q) *q = (uint16_t)v; return self; } \
776
- case CA_UINT8: { uint8_t *q=(uint8_t *)p; if ((uint8_t )v OP *q) *q = (uint8_t )v; return self; } \
777
817
  } \
778
818
  } \
779
819
  else if ( FIXNUM_P(rval) ) { \
@@ -782,13 +822,13 @@ rb_ca_elem_unmask (VALUE self, VALUE ridx)
782
822
  case CA_FLOAT64: { double *q=(double *)p; double vd=(double)v; if (vd OP *q || *q != *q) *q = vd; return self; } \
783
823
  case CA_FLOAT32: { float *q=(float *)p; float vf=(float )v; if (vf OP *q || *q != *q) *q = vf; return self; } \
784
824
  case CA_INT64: { int64_t *q=(int64_t *)p; if ((int64_t)v OP *q) *q = (int64_t)v; return self; } \
785
- case CA_INT32: { int32_t *q=(int32_t *)p; if ((int32_t)v OP *q) *q = (int32_t)v; return self; } \
786
- case CA_INT16: { int16_t *q=(int16_t *)p; if ((int16_t)v OP *q) *q = (int16_t)v; return self; } \
787
- case CA_INT8: { int8_t *q=(int8_t *)p; if ((int8_t )v OP *q) *q = (int8_t )v; return self; } \
788
- case CA_UINT64: { uint64_t *q=(uint64_t*)p; if ((uint64_t)v OP *q) *q = (uint64_t)v; return self; } \
789
- case CA_UINT32: { uint32_t *q=(uint32_t*)p; if ((uint32_t)v OP *q) *q = (uint32_t)v; return self; } \
790
- case CA_UINT16: { uint16_t *q=(uint16_t*)p; if ((uint16_t)v OP *q) *q = (uint16_t)v; return self; } \
791
- case CA_UINT8: { uint8_t *q=(uint8_t *)p; if ((uint8_t )v OP *q) *q = (uint8_t )v; return self; } \
825
+ case CA_INT32: { if ( ! (v >= INT32_MIN && v <= INT32_MAX) ) break; int32_t *q=(int32_t *)p; if ((int32_t)v OP *q) *q = (int32_t)v; return self; } \
826
+ case CA_INT16: { if ( ! (v >= INT16_MIN && v <= INT16_MAX) ) break; int16_t *q=(int16_t *)p; if ((int16_t)v OP *q) *q = (int16_t)v; return self; } \
827
+ case CA_INT8: { if ( ! (v >= INT8_MIN && v <= INT8_MAX) ) break; int8_t *q=(int8_t *)p; if ((int8_t )v OP *q) *q = (int8_t )v; return self; } \
828
+ case CA_UINT64: { if ( ! (v >= 0) ) break; uint64_t *q=(uint64_t*)p; if ((uint64_t)v OP *q) *q = (uint64_t)v; return self; } \
829
+ case CA_UINT32: { if ( ! (v >= 0 && v <= (long) UINT32_MAX) ) break; uint32_t *q=(uint32_t*)p; if ((uint32_t)v OP *q) *q = (uint32_t)v; return self; } \
830
+ case CA_UINT16: { if ( ! (v >= 0 && v <= (long) UINT16_MAX) ) break; uint16_t *q=(uint16_t*)p; if ((uint16_t)v OP *q) *q = (uint16_t)v; return self; } \
831
+ case CA_UINT8: { if ( ! (v >= 0 && v <= (long) UINT8_MAX) ) break; uint8_t *q=(uint8_t *)p; if ((uint8_t )v OP *q) *q = (uint8_t )v; return self; } \
792
832
  } \
793
833
  } \
794
834
  } \
@@ -808,6 +848,10 @@ rb_ca_elem_min (VALUE self, VALUE ridx, VALUE rval)
808
848
  rb_raise(rb_eCADataTypeError,
809
849
  "elem_min requires a numeric array");
810
850
  }
851
+ if ( ca_is_complex_type(ca) ) {
852
+ rb_raise(rb_eCADataTypeError,
853
+ "elem_min requires a real array (complex values have no order)");
854
+ }
811
855
 
812
856
  /* Super-hot path: entity + numeric data type + Fixnum/Float rval. */
813
857
  ELEM_MINMAX_BODY(<);
@@ -864,6 +908,10 @@ rb_ca_elem_max (VALUE self, VALUE ridx, VALUE rval)
864
908
  rb_raise(rb_eCADataTypeError,
865
909
  "elem_max requires a numeric array");
866
910
  }
911
+ if ( ca_is_complex_type(ca) ) {
912
+ rb_raise(rb_eCADataTypeError,
913
+ "elem_max requires a real array (complex values have no order)");
914
+ }
867
915
 
868
916
  ELEM_MINMAX_BODY(>);
869
917