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.
Files changed (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +824 -0
  3. data/README.md +5 -6
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_dispatch.c +258 -4
  6. data/ext/ca_axis_group.c +368 -184
  7. data/ext/ca_binop_dispatch.c +54 -32
  8. data/ext/ca_binop_dispatch.h +1 -0
  9. data/ext/ca_categorical_iterator.c +90 -41
  10. data/ext/ca_compare.c +8 -2
  11. data/ext/ca_for_buffer.h +21 -68
  12. data/ext/ca_group_iter.c +27 -11
  13. data/ext/ca_kernel_iterator.c +960 -245
  14. data/ext/ca_kernel_iterator.h +352 -181
  15. data/ext/ca_monop_dispatch.c +4 -4
  16. data/ext/ca_monop_dispatch.h +4 -0
  17. data/ext/ca_obj_array.c +194 -42
  18. data/ext/ca_obj_bincmp.c +152 -121
  19. data/ext/ca_obj_binop.c +107 -210
  20. data/ext/ca_obj_bitarray.c +37 -24
  21. data/ext/ca_obj_bitfield.c +95 -62
  22. data/ext/ca_obj_block.c +5 -4
  23. data/ext/ca_obj_byte_swap.c +40 -40
  24. data/ext/ca_obj_const_string.c +180 -50
  25. data/ext/ca_obj_face.c +428 -62
  26. data/ext/ca_obj_face.h +107 -47
  27. data/ext/ca_obj_fake.c +21 -50
  28. data/ext/ca_obj_farray.c +1 -0
  29. data/ext/ca_obj_field.c +16 -3
  30. data/ext/ca_obj_fixlen_string.c +39 -26
  31. data/ext/ca_obj_grid.c +181 -124
  32. data/ext/ca_obj_meld.c +235 -55
  33. data/ext/ca_obj_moncmp.c +61 -61
  34. data/ext/ca_obj_monop.c +125 -107
  35. data/ext/ca_obj_object.c +551 -233
  36. data/ext/ca_obj_record.c +51 -16
  37. data/ext/ca_obj_reduce.c +5 -8
  38. data/ext/ca_obj_refer.c +117 -33
  39. data/ext/ca_obj_remap.c +57 -17
  40. data/ext/ca_obj_repeat.c +21 -5
  41. data/ext/ca_obj_roll.c +115 -11
  42. data/ext/ca_obj_select.c +88 -75
  43. data/ext/ca_obj_select_axis.c +58 -60
  44. data/ext/ca_obj_shift.c +22 -102
  45. data/ext/ca_obj_stack.c +223 -123
  46. data/ext/ca_obj_stride.c +267 -35
  47. data/ext/ca_obj_string.c +25 -22
  48. data/ext/ca_obj_tile.c +32 -16
  49. data/ext/ca_obj_time.c +23 -25
  50. data/ext/ca_obj_timedelta.c +21 -23
  51. data/ext/ca_obj_transpose.c +12 -3
  52. data/ext/ca_obj_triop.c +110 -117
  53. data/ext/ca_obj_window.c +157 -29
  54. data/ext/ca_op_ipower.c +25 -13
  55. data/ext/ca_op_powi.h +57 -30
  56. data/ext/ca_pow5_table.h +656 -0
  57. data/ext/ca_rng_normal.h +42 -0
  58. data/ext/ca_rng_xoshiro256pp.h +105 -0
  59. data/ext/ca_sort_kernels.h +70 -0
  60. data/ext/ca_sweep_engine.c +385 -198
  61. data/ext/ca_sweep_engine.h +31 -23
  62. data/ext/ca_triop_dispatch.c +4 -1
  63. data/ext/ca_triop_dispatch.h +5 -2
  64. data/ext/caframe_csv_reader.c +463 -0
  65. data/ext/carray.h +90 -28
  66. data/ext/carray_access.c +487 -231
  67. data/ext/carray_address_basis.c +731 -0
  68. data/ext/carray_attribute.c +45 -3
  69. data/ext/carray_bincount.c +32 -2
  70. data/ext/carray_broadcast.c +49 -17
  71. data/ext/carray_call_cfunc.c +667 -511
  72. data/ext/carray_cast.c +1556 -247
  73. data/ext/carray_cast_func.rb +34 -21
  74. data/ext/carray_conversion.c +197 -73
  75. data/ext/carray_copy.c +84 -38
  76. data/ext/carray_core.c +591 -119
  77. data/ext/carray_count.c +148 -96
  78. data/ext/carray_element.c +18 -27
  79. data/ext/carray_factorize.c +604 -291
  80. data/ext/carray_generate.c +76 -40
  81. data/ext/carray_histogram.c +152 -94
  82. data/ext/carray_hold.c +2 -1
  83. data/ext/carray_index_classifier.c +63 -96
  84. data/ext/carray_internal.h +400 -1
  85. data/ext/carray_lazy.c +834 -79
  86. data/ext/carray_loop.c +88 -66
  87. data/ext/carray_mask.c +705 -324
  88. data/ext/carray_math_kernel.h +1 -0
  89. data/ext/carray_median_percentile.c +263 -63
  90. data/ext/carray_memory_view.c +254 -248
  91. data/ext/carray_operator.c +1093 -363
  92. data/ext/carray_order.c +133 -69
  93. data/ext/carray_partition.c +102 -56
  94. data/ext/carray_random.c +582 -204
  95. data/ext/carray_scatter.c +308 -65
  96. data/ext/carray_segment.c +257 -0
  97. data/ext/carray_slab.c +183 -70
  98. data/ext/carray_sort.c +235 -240
  99. data/ext/carray_sort_kernel.c +8 -1
  100. data/ext/carray_struct.c +99 -21
  101. data/ext/carray_test.c +167 -64
  102. data/ext/carray_time_text.c +1182 -0
  103. data/ext/carray_utils.c +363 -98
  104. data/ext/extconf.rb +27 -2
  105. data/ext/mk_call_cfunc.rb +103 -118
  106. data/ext/mk_pow5_table.rb +35 -0
  107. data/ext/mkkernel.rb +1349 -851
  108. data/ext/ruby_carray.c +17 -2
  109. data/ext/version.h +4 -4
  110. data/ext/version.rb +4 -2
  111. data/lib/carray/attribute.rb +39 -0
  112. data/lib/carray/autoload_carray.rb +24 -3
  113. data/lib/carray/autoload_method_extension.rb +18 -0
  114. data/lib/carray/axis_group.rb +245 -20
  115. data/lib/carray/basics.rb +95 -25
  116. data/lib/carray/bincount_nd.rb +6 -0
  117. data/lib/carray/block_iterator.rb +200 -54
  118. data/lib/carray/boolean_reduce.rb +21 -29
  119. data/lib/carray/categorical.rb +244 -59
  120. data/lib/carray/categorical_iterator.rb +391 -757
  121. data/lib/carray/complex.rb +36 -29
  122. data/lib/carray/conditional.rb +94 -7
  123. data/lib/carray/const_string.rb +177 -27
  124. data/lib/carray/construct.rb +40 -0
  125. data/lib/carray/data_type_extension.rb +3 -0
  126. data/lib/carray/data_type_limits.rb +91 -0
  127. data/lib/carray/fixlen_string.rb +1 -1
  128. data/lib/carray/frame/concat.rb +157 -6
  129. data/lib/carray/frame/convert.rb +13 -7
  130. data/lib/carray/frame/csv_parser.rb +590 -76
  131. data/lib/carray/frame/describe.rb +79 -0
  132. data/lib/carray/frame/frame.rb +205 -35
  133. data/lib/carray/frame/group.rb +199 -40
  134. data/lib/carray/frame/io.rb +452 -60
  135. data/lib/carray/frame/join.rb +134 -46
  136. data/lib/carray/frame/records.rb +54 -19
  137. data/lib/carray/frame/reshape.rb +448 -0
  138. data/lib/carray/frame/sort.rb +26 -2
  139. data/lib/carray/frame/verbs.rb +726 -56
  140. data/lib/carray/frame.rb +2 -0
  141. data/lib/carray/fuse_source.rb +111 -2
  142. data/lib/carray/fusion.rb +229 -38
  143. data/lib/carray/inspect.rb +71 -20
  144. data/lib/carray/iterator.rb +157 -2
  145. data/lib/carray/lazy.rb +54 -67
  146. data/lib/carray/mask_gap_fill.rb +66 -50
  147. data/lib/carray/math.rb +32 -19
  148. data/lib/carray/meld_reduce.rb +40 -7
  149. data/lib/carray/methods/align_addr.rb +8 -4
  150. data/lib/carray/methods/bincount.rb +2 -2
  151. data/lib/carray/methods/bit_string.rb +14 -3
  152. data/lib/carray/methods/composition.rb +16 -10
  153. data/lib/carray/methods/discovery_along.rb +74 -0
  154. data/lib/carray/methods/factorize.rb +50 -0
  155. data/lib/carray/methods/gather_nd.rb +13 -2
  156. data/lib/carray/methods/insert_block.rb +9 -14
  157. data/lib/carray/methods/is_in.rb +130 -6
  158. data/lib/carray/methods/join.rb +1 -1
  159. data/lib/carray/methods/locate_addr.rb +235 -21
  160. data/lib/carray/methods/mask_duplicates.rb +35 -1
  161. data/lib/carray/methods/mode.rb +18 -1
  162. data/lib/carray/methods/nunique.rb +22 -1
  163. data/lib/carray/methods/repeat.rb +91 -0
  164. data/lib/carray/methods/resize.rb +21 -23
  165. data/lib/carray/methods/snap.rb +34 -12
  166. data/lib/carray/methods/unique.rb +52 -3
  167. data/lib/carray/record_order.rb +208 -0
  168. data/lib/carray/rng.rb +86 -0
  169. data/lib/carray/runtime.rb +14 -11
  170. data/lib/carray/segment_iterator.rb +990 -0
  171. data/lib/carray/serialize.rb +197 -27
  172. data/lib/carray/slab_iterator.rb +109 -40
  173. data/lib/carray/stack.rb +10 -4
  174. data/lib/carray/string_operation_extension.rb +9 -4
  175. data/lib/carray/struct.rb +142 -51
  176. data/lib/carray/struct_builder.rb +110 -14
  177. data/lib/carray/table.rb +2 -2
  178. data/lib/carray/time.rb +535 -105
  179. data/lib/carray/window_iterator.rb +259 -82
  180. data/lib/carray.rb +4 -2
  181. data/yard-stubs/ca_obj_array.rb +4 -4
  182. data/yard-stubs/ca_obj_bitarray.rb +7 -0
  183. data/yard-stubs/ca_obj_bitfield.rb +23 -12
  184. data/yard-stubs/ca_obj_block.rb +2 -7
  185. data/yard-stubs/ca_obj_fake.rb +1 -1
  186. data/yard-stubs/ca_obj_field.rb +1 -1
  187. data/yard-stubs/ca_obj_refer.rb +3 -3
  188. data/yard-stubs/ca_obj_roll.rb +0 -1
  189. data/yard-stubs/ca_obj_stride.rb +10 -7
  190. data/yard-stubs/ca_obj_transpose.rb +1 -1
  191. data/yard-stubs/ca_obj_window.rb +11 -4
  192. data/yard-stubs/carray_access.rb +6 -5
  193. data/yard-stubs/carray_broadcast.rb +2 -2
  194. data/yard-stubs/carray_cast.rb +78 -43
  195. data/yard-stubs/carray_conversion.rb +13 -1
  196. data/yard-stubs/carray_copy.rb +8 -3
  197. data/yard-stubs/carray_core.rb +3 -83
  198. data/yard-stubs/carray_count.rb +16 -2
  199. data/yard-stubs/carray_lazy.rb +210 -1
  200. data/yard-stubs/carray_loop.rb +4 -1
  201. data/yard-stubs/carray_mask.rb +34 -10
  202. data/yard-stubs/carray_math.rb +1499 -4
  203. data/yard-stubs/carray_median_percentile.rb +26 -8
  204. data/yard-stubs/carray_order.rb +43 -82
  205. data/yard-stubs/carray_scatter.rb +10 -3
  206. data/yard-stubs/carray_segment.rb +72 -0
  207. data/yard-stubs/carray_slab.rb +11 -8
  208. data/yard-stubs/carray_sort.rb +50 -8
  209. data/yard-stubs/carray_test.rb +10 -0
  210. data/yard-stubs/carray_utils.rb +0 -26
  211. metadata +19 -19
  212. data/ext/ca_for_each_element.h +0 -239
  213. data/ext/carray_build_flags.h +0 -3
  214. data/ext/carray_config.h +0 -28
  215. data/ext/carray_kernels_bincmp.c +0 -4446
  216. data/ext/carray_kernels_binop.c +0 -11001
  217. data/ext/carray_kernels_init.c +0 -1131
  218. data/ext/carray_kernels_map.c +0 -3467
  219. data/ext/carray_kernels_moncmp.c +0 -2097
  220. data/ext/carray_kernels_monop.c +0 -18313
  221. data/ext/carray_kernels_reduce_aggregate.c +0 -25837
  222. data/ext/carray_kernels_reduce_boolean.c +0 -330
  223. data/ext/carray_kernels_reduce_cumulative.c +0 -14593
  224. data/ext/carray_kernels_reduce_extreme.c +0 -16948
  225. data/ext/carray_kernels_reduce_variance.c +0 -3910
  226. data/ext/carray_kernels_scan.c +0 -3693
  227. data/ext/carray_kernels_search.c +0 -32138
  228. data/ext/carray_kernels_sort.c +0 -10626
  229. data/ext/carray_kernels_triop.c +0 -1392
@@ -21,6 +21,7 @@
21
21
  --------------------------------------------------------------------------- */
22
22
 
23
23
  #include "carray.h"
24
+ #include "carray_internal.h" /* ca_index_in_range_at */
24
25
  #include "carray_index_classifier.h"
25
26
 
26
27
  /* Range accessor macros — carray_access.c keeps a private cache
@@ -85,13 +86,12 @@ typedef struct {
85
86
  static inline ca_size_t
86
87
  ca_classifier_normalize_axis_index (ca_size_t k, ca_size_t dim, int axis, int range_check)
87
88
  {
89
+ ca_size_t given = k;
88
90
  if ( k < 0 ) {
89
91
  k += dim;
90
92
  }
91
93
  if ( range_check && ( k < 0 || k >= dim ) ) {
92
- rb_raise(rb_eIndexError,
93
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
94
- axis, (ca_size_t) k, (ca_size_t) (dim - 1));
94
+ ca_index_out_of_range_at(given, dim, axis);
95
95
  }
96
96
  return k;
97
97
  }
@@ -177,9 +177,8 @@ ca_classifier_check_reserved_contraction_symbol (VALUE sym)
177
177
  && ( ( name[0] >= 'a' && name[0] <= 'z' )
178
178
  || ( name[0] >= 'A' && name[0] <= 'Z' ) )
179
179
  && name[0] != '_' /* :_ is iterator marker, handled separately */ ) {
180
- rb_raise(rb_eNotImpError,
181
- "symbol :%s is reserved for future contraction notation "
182
- "(not yet implemented)",
180
+ rb_raise(rb_eIndexError,
181
+ "symbol :%s is reserved for future contraction notation",
183
182
  name);
184
183
  }
185
184
  }
@@ -214,14 +213,7 @@ ca_classifier_axis_from_range (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
214
213
  info->index_type[axis] = CA_IDX_BLOCK;
215
214
 
216
215
  if ( info->range_check ) {
217
- /* Inlined CA_CHECK_INDEX_AT so the format string stays
218
- byte-identical with the surrounding helpers. */
219
- if ( start < 0 ) start += dim;
220
- if ( start < 0 || start >= dim ) {
221
- rb_raise(rb_eIndexError,
222
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
223
- axis, (ca_size_t) start, (ca_size_t) (dim - 1));
224
- }
216
+ start = ca_index_in_range_at(start, dim, axis);
225
217
  }
226
218
 
227
219
  if ( last < 0 ) {
@@ -238,9 +230,7 @@ ca_classifier_axis_from_range (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
238
230
  }
239
231
  if ( info->range_check ) {
240
232
  if ( last < 0 || last >= dim ) {
241
- rb_raise(rb_eIndexError,
242
- "index %" PRId64 " is out of range (0..%" PRId64 ") at %i-dim",
243
- (ca_size_t) last, (ca_size_t) (dim - 1), axis);
233
+ ca_index_out_of_range_at(last, dim, axis);
244
234
  }
245
235
  }
246
236
  count = llabs(last - start) + 1;
@@ -273,7 +263,7 @@ ca_classifier_axis_from_arithseq (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
273
263
  excl = RTEST(iv_excl);
274
264
 
275
265
  if ( step == 0 ) {
276
- rb_raise(rb_eRuntimeError,
266
+ rb_raise(rb_eArgError,
277
267
  "step in index equals to 0 in block reference");
278
268
  }
279
269
 
@@ -283,12 +273,7 @@ ca_classifier_axis_from_arithseq (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
283
273
  ignoring info->range_check. An ArithSeq with a negative or
284
274
  out-of-range start silently produces an empty region if this
285
275
  check is deferred, which upstream callers do not expect. */
286
- if ( start < 0 ) start += dim;
287
- if ( start < 0 || start >= dim ) {
288
- rb_raise(rb_eIndexError,
289
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
290
- axis, (ca_size_t) start, (ca_size_t) (dim - 1));
291
- }
276
+ start = ca_index_in_range_at(start, dim, axis);
292
277
 
293
278
  if ( last < 0 ) {
294
279
  last += dim;
@@ -303,23 +288,23 @@ ca_classifier_axis_from_arithseq (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
303
288
  last += ( last >= start ) ? -1 : 1;
304
289
  }
305
290
  if ( last < 0 || last >= dim ) {
306
- rb_raise(rb_eIndexError,
307
- "index %" PRId64 " is out of range (0..%" PRId64 ") at %i-dim",
308
- (ca_size_t) last, (ca_size_t) (dim - 1), axis);
291
+ ca_index_out_of_range_at(last, dim, axis);
309
292
  }
310
- if ( (last - start) * (long long) step < 0 ) {
293
+ /* start and last are both inside the axis, so their distance fits; the
294
+ step is taken by magnitude unsigned, since -step overflows at its
295
+ minimum. (count - 1) * step below is then at most that distance. */
296
+ if ( (last > start && step < 0) || (last < start && step > 0) ) {
311
297
  count = 1;
312
298
  }
313
299
  else {
314
- count = llabs(last - start) / llabs((long long) step) + 1;
300
+ unsigned long long span = (unsigned long long)
301
+ (last >= start ? last - start : start - last);
302
+ unsigned long long ustep = step < 0 ? 0ULL - (unsigned long long) step
303
+ : (unsigned long long) step;
304
+ count = (ca_size_t) (span / ustep) + 1;
315
305
  }
316
306
  bound = start + (count - 1) * step;
317
- if ( bound < 0 ) bound += dim; /* CA_CHECK_INDEX_AT signature */
318
- if ( bound < 0 || bound >= dim ) {
319
- rb_raise(rb_eIndexError,
320
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
321
- axis, (ca_size_t) bound, (ca_size_t) (dim - 1));
322
- }
307
+ bound = ca_index_in_range_at(bound, dim, axis);
323
308
  info->index[axis].block.start = start;
324
309
  info->index[axis].block.count = count;
325
310
  info->index[axis].block.step = step;
@@ -350,13 +335,9 @@ ca_classifier_axis_from_array (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
350
335
  }
351
336
  /* [Integer] */
352
337
  {
353
- ca_size_t start = NUM2SIZE(a0);
354
- if ( start < 0 ) start += dim;
355
- if ( start < 0 || start >= dim ) {
356
- rb_raise(rb_eIndexError,
357
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
358
- axis, (ca_size_t) start, (ca_size_t) (dim - 1));
359
- }
338
+ ca_size_t given = NUM2SIZE(a0);
339
+ ca_size_t start = given;
340
+ start = ca_index_in_range_at(start, dim, axis);
360
341
  info->index[axis].block.start = start;
361
342
  info->index[axis].block.count = 1;
362
343
  info->index[axis].block.step = 1;
@@ -372,18 +353,13 @@ ca_classifier_axis_from_array (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
372
353
  ca_size_t start = 0, last, count, step, bound;
373
354
  step = NUM2SIZE(a1);
374
355
  if ( step == 0 ) {
375
- rb_raise(rb_eRuntimeError,
356
+ rb_raise(rb_eArgError,
376
357
  "step in index equals to 0 in block reference");
377
358
  }
378
359
  last = dim - 1;
379
360
  count = ( step < 0 ) ? 1 : (last / step + 1);
380
361
  bound = start + (count - 1) * step;
381
- if ( bound < 0 ) bound += dim;
382
- if ( bound < 0 || bound >= dim ) {
383
- rb_raise(rb_eIndexError,
384
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
385
- axis, (ca_size_t) bound, (ca_size_t) (dim - 1));
386
- }
362
+ bound = ca_index_in_range_at(bound, dim, axis);
387
363
  info->index[axis].block.start = start;
388
364
  info->index[axis].block.count = count;
389
365
  info->index[axis].block.step = step;
@@ -402,15 +378,10 @@ ca_classifier_axis_from_array (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
402
378
  excl = RTEST(iv_excl);
403
379
  step = NUM2SIZE(a1);
404
380
  if ( step == 0 ) {
405
- rb_raise(rb_eRuntimeError,
381
+ rb_raise(rb_eArgError,
406
382
  "step in index equals to 0 in block reference");
407
383
  }
408
- if ( start < 0 ) start += dim;
409
- if ( start < 0 || start >= dim ) {
410
- rb_raise(rb_eIndexError,
411
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
412
- axis, (ca_size_t) start, (ca_size_t) (dim - 1));
413
- }
384
+ start = ca_index_in_range_at(start, dim, axis);
414
385
  if ( last < 0 ) last += dim;
415
386
  if ( excl && start == last ) {
416
387
  info->index[axis].block.start = start;
@@ -422,23 +393,20 @@ ca_classifier_axis_from_array (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
422
393
  last += ( last >= start ) ? -1 : 1;
423
394
  }
424
395
  if ( last < 0 || last >= dim ) {
425
- rb_raise(rb_eIndexError,
426
- "index %" PRId64 " is out of range (0..%" PRId64 ") at %i-dim",
427
- (ca_size_t) last, (ca_size_t) (dim - 1), axis);
396
+ ca_index_out_of_range_at(last, dim, axis);
428
397
  }
429
- if ( (last - start) * (long long) step < 0 ) {
398
+ if ( (last > start && step < 0) || (last < start && step > 0) ) {
430
399
  count = 1;
431
400
  }
432
401
  else {
433
- count = llabs(last - start) / llabs((long long) step) + 1;
402
+ unsigned long long span = (unsigned long long)
403
+ (last >= start ? last - start : start - last);
404
+ unsigned long long ustep = step < 0 ? 0ULL - (unsigned long long) step
405
+ : (unsigned long long) step;
406
+ count = (ca_size_t) (span / ustep) + 1;
434
407
  }
435
408
  bound = start + (count - 1) * step;
436
- if ( bound < 0 ) bound += dim;
437
- if ( bound < 0 || bound >= dim ) {
438
- rb_raise(rb_eIndexError,
439
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
440
- axis, (ca_size_t) bound, (ca_size_t) (dim - 1));
441
- }
409
+ bound = ca_index_in_range_at(bound, dim, axis);
442
410
  info->index[axis].block.start = start;
443
411
  info->index[axis].block.count = count;
444
412
  info->index[axis].block.step = step;
@@ -450,19 +418,15 @@ ca_classifier_axis_from_array (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
450
418
  ca_size_t start, count, bound;
451
419
  start = NUM2SIZE(a0);
452
420
  count = NUM2SIZE(a1);
453
- bound = start + (count - 1);
454
- if ( start < 0 ) start += dim;
455
- if ( start < 0 || start >= dim ) {
421
+ if ( __builtin_add_overflow(start, count - 1, &bound) ) {
456
422
  rb_raise(rb_eIndexError,
457
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
458
- axis, (ca_size_t) start, (ca_size_t) (dim - 1));
459
- }
460
- if ( bound < 0 ) bound += dim;
461
- if ( bound < 0 || bound >= dim ) {
462
- rb_raise(rb_eIndexError,
463
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
464
- axis, (ca_size_t) bound, (ca_size_t) (dim - 1));
423
+ "%s: index [%" PRId64 ", %" PRId64 "] is out of range for "
424
+ "length %" PRId64 " on axis %i",
425
+ ca_calling_method_name(), (ca_size_t) start, (ca_size_t) count,
426
+ (ca_size_t) dim, axis);
465
427
  }
428
+ start = ca_index_in_range_at(start, dim, axis);
429
+ bound = ca_index_in_range_at(bound, dim, axis);
466
430
  info->index[axis].block.start = start;
467
431
  info->index[axis].block.count = count;
468
432
  info->index[axis].block.step = 1;
@@ -476,22 +440,21 @@ ca_classifier_axis_from_array (ca_classifier_ctx_t *ctx, int axis, VALUE arg)
476
440
  count = NUM2SIZE(rb_ary_entry(arg, 1));
477
441
  step = NUM2SIZE(rb_ary_entry(arg, 2));
478
442
  if ( step == 0 ) {
479
- rb_raise(rb_eRuntimeError,
443
+ rb_raise(rb_eArgError,
480
444
  "step in index equals to 0 in block reference");
481
445
  }
482
- bound = start + (count - 1) * step;
483
- if ( start < 0 ) start += dim;
484
- if ( start < 0 || start >= dim ) {
485
- rb_raise(rb_eIndexError,
486
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
487
- axis, (ca_size_t) start, (ca_size_t) (dim - 1));
488
- }
489
- if ( bound < 0 ) bound += dim;
490
- if ( bound < 0 || bound >= dim ) {
446
+ /* A count and a step whose last cell lies past the range of an index
447
+ are out of range, not a wrapped bound that lands back inside. */
448
+ if ( __builtin_mul_overflow(count - 1, step, &bound) ||
449
+ __builtin_add_overflow(start, bound, &bound) ) {
491
450
  rb_raise(rb_eIndexError,
492
- "index out of range at %i-dim ( %" PRId64 " <=> 0..%" PRId64 " )",
493
- axis, (ca_size_t) bound, (ca_size_t) (dim - 1));
451
+ "%s: index [%" PRId64 ", %" PRId64 ", %" PRId64 "] is out of "
452
+ "range for length %" PRId64 " on axis %i",
453
+ ca_calling_method_name(), (ca_size_t) start, (ca_size_t) count,
454
+ (ca_size_t) step, (ca_size_t) dim, axis);
494
455
  }
456
+ start = ca_index_in_range_at(start, dim, axis);
457
+ bound = ca_index_in_range_at(bound, dim, axis);
495
458
  info->index[axis].block.start = start;
496
459
  info->index[axis].block.count = count;
497
460
  info->index[axis].block.step = step;
@@ -565,9 +528,9 @@ ca_classifier_dispatch_axis_arg (ca_classifier_ctx_t *ctx, int axis, VALUE arg,
565
528
  }
566
529
  ca_classifier_check_reserved_contraction_symbol(arg); /* raises if reserved */
567
530
  rb_raise(rb_eIndexError,
568
- "symbol :%s is invalid as the index for slab iterator "
531
+ "symbol :%"PRIsVALUE" is invalid as the index for slab iterator "
569
532
  "(use :> instead)",
570
- rb_id2name(SYM2ID(arg)));
533
+ rb_sym2str(arg));
571
534
  }
572
535
  if ( rb_obj_is_carray(arg) ) {
573
536
  /* CArray (boolean / integer) at an axis position → GRID.
@@ -622,7 +585,7 @@ ca_classifier_expand_rubber_dim (ca_classifier_ctx_t *ctx)
622
585
  /* No rubber dim — validate argc == ndim and pass through. */
623
586
  if ( argc != ctx->ca_ndim ) {
624
587
  rb_raise(rb_eIndexError,
625
- "number of indices exceeds the ndim of carray (%i > %i)",
588
+ "%i indices given for a carray of ndim %i",
626
589
  (int) argc, ctx->ca_ndim);
627
590
  }
628
591
  return;
@@ -745,7 +708,7 @@ ca_classifier_try_argc1_special (ca_classifier_ctx_t *ctx)
745
708
  }
746
709
  if ( ca_is_boolean_type(cs) ) {
747
710
  if ( ctx->ca_elements != cs->elements ) {
748
- rb_raise(rb_eRuntimeError,
711
+ rb_raise(rb_eArgError,
749
712
  "mismatch of # of elements ( %" PRId64 " <=> %" PRId64 " ) "
750
713
  "in reference by selection",
751
714
  (ca_size_t) cs->elements,
@@ -878,7 +841,7 @@ rb_ca_scan_index_v2 (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
878
841
  here would raise on legitimate grid regions. */
879
842
  if ( ! is_grid && ctx.ca_ndim != info->ndim ) {
880
843
  rb_raise(rb_eIndexError,
881
- "number of indices does not equal to the ndim (%i != %i)",
844
+ "%i indices given for a carray of ndim %i",
882
845
  info->ndim, ctx.ca_ndim);
883
846
  }
884
847
 
@@ -886,6 +849,7 @@ rb_ca_scan_index_v2 (int ca_ndim, ca_size_t *ca_dim, ca_size_t ca_elements,
886
849
  }
887
850
  }
888
851
 
852
+ #ifdef CARRAY_DEV_BUILD
889
853
  /* -------------------------------------------------------------------- */
890
854
  /* Debug / test surface: CArray._scan_index_v2(dim_array, idx_array)
891
855
  returns a plain [type_int, index_array] pair rather than the
@@ -1001,7 +965,7 @@ rb_ca_s_scan_index_v2 (VALUE self, VALUE rdim, VALUE ridx)
1001
965
  info.index[i].symbol.spec));
1002
966
  break;
1003
967
  default:
1004
- rb_raise(rb_eRuntimeError, "unknown index spec");
968
+ rb_raise(rb_eIndexError, "unknown index spec");
1005
969
  }
1006
970
  }
1007
971
  break;
@@ -1011,11 +975,14 @@ rb_ca_s_scan_index_v2 (VALUE self, VALUE rdim, VALUE ridx)
1011
975
 
1012
976
  return rb_ary_new3(2, INT2NUM(info.type), rindex);
1013
977
  }
978
+ #endif
1014
979
 
1015
980
  void
1016
981
  Init_carray_index_classifier (void)
1017
982
  {
1018
983
  ca_classifier_sym_cache_init();
984
+ #ifdef CARRAY_DEV_BUILD
1019
985
  rb_define_singleton_method(rb_cCArray, "_scan_index_v2",
1020
986
  rb_ca_s_scan_index_v2, 2);
987
+ #endif
1021
988
  }