carray 2.0.1 → 3.0.1

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 (386) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -25
  3. data/CHANGELOG.md +338 -0
  4. data/{NEWS.md → CHANGELOG.v1.md} +3 -0
  5. data/LICENSE +1 -1
  6. data/README.md +120 -36
  7. data/carray.gemspec +32 -30
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1244 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +124 -0
  15. data/ext/ca_binop_dispatch.h +152 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +239 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4367 -0
  26. data/ext/ca_kernel_iterator.h +2596 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +839 -0
  33. data/ext/ca_obj_binop.c +948 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +967 -0
  39. data/ext/ca_obj_face.c +750 -0
  40. data/ext/ca_obj_face.h +279 -0
  41. data/ext/ca_obj_fake.c +239 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +308 -0
  45. data/ext/ca_obj_grid.c +866 -440
  46. data/ext/ca_obj_meld.c +1039 -0
  47. data/ext/ca_obj_moncmp.c +588 -0
  48. data/ext/ca_obj_monop.c +1123 -0
  49. data/ext/ca_obj_object.c +866 -296
  50. data/ext/ca_obj_record.c +470 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +593 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +624 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1306 -0
  58. data/ext/ca_obj_shift.c +231 -793
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2584 -0
  62. data/ext/ca_obj_string.c +270 -0
  63. data/ext/ca_obj_tile.c +622 -0
  64. data/ext/ca_obj_time.c +548 -0
  65. data/ext/ca_obj_timedelta.c +437 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +785 -0
  68. data/ext/ca_obj_window.c +1202 -565
  69. data/ext/ca_op_byte_swap.c +175 -0
  70. data/ext/ca_op_cmplx64.h +123 -0
  71. data/ext/ca_op_ipower.c +316 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +473 -0
  75. data/ext/ca_sweep_engine.h +166 -0
  76. data/ext/ca_transform_common.c +235 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +810 -420
  80. data/ext/carray_access.c +873 -731
  81. data/ext/carray_attribute.c +98 -329
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +376 -0
  84. data/ext/carray_build_flags.h +3 -0
  85. data/ext/carray_call_cfunc.c +2897 -874
  86. data/ext/carray_call_cfunc.h +313 -0
  87. data/ext/carray_cast.c +1264 -315
  88. data/ext/carray_cast_func.rb +81 -40
  89. data/ext/carray_class.c +53 -63
  90. data/ext/carray_config.h +28 -0
  91. data/ext/carray_conversion.c +350 -346
  92. data/ext/carray_copy.c +168 -270
  93. data/ext/carray_core.c +1396 -206
  94. data/ext/carray_count.c +312 -0
  95. data/ext/carray_data_type.c +43 -19
  96. data/ext/carray_element.c +585 -213
  97. data/ext/carray_factorize.c +2542 -0
  98. data/ext/carray_generate.c +230 -559
  99. data/ext/carray_histogram.c +490 -0
  100. data/ext/carray_hold.c +228 -0
  101. data/ext/carray_index_classifier.c +1021 -0
  102. data/ext/carray_index_classifier.h +27 -0
  103. data/ext/carray_internal.h +136 -0
  104. data/ext/carray_kernels_bincmp.c +4446 -0
  105. data/ext/carray_kernels_binop.c +11001 -0
  106. data/ext/carray_kernels_init.c +1131 -0
  107. data/ext/carray_kernels_map.c +3467 -0
  108. data/ext/carray_kernels_moncmp.c +2097 -0
  109. data/ext/carray_kernels_monop.c +18313 -0
  110. data/ext/carray_kernels_reduce_aggregate.c +25837 -0
  111. data/ext/carray_kernels_reduce_boolean.c +330 -0
  112. data/ext/carray_kernels_reduce_cumulative.c +14593 -0
  113. data/ext/carray_kernels_reduce_extreme.c +16948 -0
  114. data/ext/carray_kernels_reduce_variance.c +3910 -0
  115. data/ext/carray_kernels_scan.c +3693 -0
  116. data/ext/carray_kernels_search.c +32138 -0
  117. data/ext/carray_kernels_sort.c +10626 -0
  118. data/ext/carray_kernels_triop.c +1392 -0
  119. data/ext/carray_lazy.c +737 -0
  120. data/ext/carray_loop.c +88 -200
  121. data/ext/carray_mask.c +853 -158
  122. data/ext/carray_math_kernel.h +120 -0
  123. data/ext/carray_mathfunc.c +10 -241
  124. data/ext/carray_median_percentile.c +1257 -0
  125. data/ext/carray_memory_view.c +1650 -0
  126. data/ext/carray_operator.c +1525 -320
  127. data/ext/carray_order.c +664 -1394
  128. data/ext/carray_partition.c +416 -0
  129. data/ext/carray_random.c +518 -0
  130. data/ext/carray_scatter.c +357 -0
  131. data/ext/carray_slab.c +1219 -0
  132. data/ext/carray_slab.h +84 -0
  133. data/ext/carray_sort.c +829 -0
  134. data/ext/carray_sort_kernel.c +620 -0
  135. data/ext/carray_struct.c +695 -0
  136. data/ext/carray_test.c +343 -229
  137. data/ext/carray_undef.c +34 -17
  138. data/ext/carray_utils.c +175 -74
  139. data/ext/extconf.rb +234 -55
  140. data/ext/mk_call_cfunc.rb +671 -0
  141. data/ext/mkkernel.rb +9096 -0
  142. data/ext/ruby_carray.c +211 -108
  143. data/ext/version.h +4 -14
  144. data/ext/version.rb +5 -13
  145. data/lib/carray/arrow_tensor.rb +401 -0
  146. data/lib/carray/attribute.rb +166 -0
  147. data/lib/carray/autoload_carray.rb +239 -0
  148. data/lib/carray/autoload_method_extension.rb +45 -0
  149. data/lib/carray/axis_group.rb +711 -0
  150. data/lib/carray/basics.rb +481 -0
  151. data/lib/carray/bincount_nd.rb +358 -0
  152. data/lib/carray/block_iterator.rb +614 -0
  153. data/lib/carray/boolean_reduce.rb +109 -0
  154. data/lib/carray/categorical.rb +561 -0
  155. data/lib/carray/categorical_iterator.rb +1084 -0
  156. data/lib/carray/complex.rb +150 -0
  157. data/lib/carray/conditional.rb +216 -0
  158. data/lib/carray/const_string.rb +228 -0
  159. data/lib/carray/construct.rb +160 -328
  160. data/lib/carray/core_extensions.rb +297 -0
  161. data/lib/carray/data_type_extension.rb +250 -0
  162. data/lib/carray/fixlen_string.rb +95 -0
  163. data/lib/carray/frame/concat.rb +132 -0
  164. data/lib/carray/frame/convert.rb +95 -0
  165. data/lib/carray/frame/csv_parser.rb +211 -0
  166. data/lib/carray/frame/frame.rb +642 -0
  167. data/lib/carray/frame/group.rb +186 -0
  168. data/lib/carray/frame/io.rb +321 -0
  169. data/lib/carray/frame/join.rb +248 -0
  170. data/lib/carray/frame/records.rb +99 -0
  171. data/lib/carray/frame/sort.rb +113 -0
  172. data/lib/carray/frame/verbs.rb +316 -0
  173. data/lib/carray/frame.rb +16 -0
  174. data/lib/carray/fuse_source.rb +123 -0
  175. data/lib/carray/fusion.rb +218 -0
  176. data/lib/carray/histogram.rb +512 -0
  177. data/lib/carray/inspect.rb +37 -26
  178. data/lib/carray/iterator.rb +58 -349
  179. data/lib/carray/lazy.rb +941 -0
  180. data/lib/carray/mask_gap_fill.rb +200 -0
  181. data/lib/carray/math.rb +78 -342
  182. data/lib/carray/meld_reduce.rb +289 -0
  183. data/lib/carray/methods/align_addr.rb +116 -0
  184. data/lib/carray/methods/bin.rb +128 -0
  185. data/lib/carray/methods/bincount.rb +87 -0
  186. data/lib/carray/methods/bit_string.rb +92 -0
  187. data/lib/carray/methods/broadcast.rb +63 -0
  188. data/lib/carray/methods/choose.rb +39 -0
  189. data/lib/carray/methods/composition.rb +280 -0
  190. data/lib/carray/methods/gather_nd.rb +206 -0
  191. data/lib/carray/methods/index.rb +39 -0
  192. data/lib/carray/methods/insert_block.rb +99 -0
  193. data/lib/carray/methods/is_in.rb +141 -0
  194. data/lib/carray/methods/join.rb +90 -0
  195. data/lib/carray/methods/locate_addr.rb +52 -0
  196. data/lib/carray/methods/mask_duplicates.rb +41 -0
  197. data/lib/carray/methods/meshgrid.rb +90 -0
  198. data/lib/carray/methods/mode.rb +126 -0
  199. data/lib/carray/methods/nunique.rb +46 -0
  200. data/lib/carray/methods/resize.rb +56 -0
  201. data/lib/carray/methods/snap.rb +161 -0
  202. data/lib/carray/methods/string_format.rb +57 -0
  203. data/lib/carray/methods/unique.rb +47 -0
  204. data/lib/carray/methods/value_counts.rb +71 -0
  205. data/lib/carray/mkmf.rb +124 -101
  206. data/lib/carray/runtime.rb +89 -0
  207. data/lib/carray/serialize.rb +478 -167
  208. data/lib/carray/slab_iterator.rb +305 -0
  209. data/lib/carray/stack.rb +291 -0
  210. data/lib/carray/string.rb +56 -180
  211. data/lib/carray/string_operation_extension.rb +289 -0
  212. data/lib/carray/struct.rb +335 -323
  213. data/lib/carray/struct_builder.rb +697 -0
  214. data/lib/carray/table.rb +41 -2
  215. data/lib/carray/time.rb +2654 -38
  216. data/lib/carray/window_iterator.rb +927 -0
  217. data/lib/carray.rb +55 -57
  218. data/yard-stubs/ca_obj_array.rb +385 -0
  219. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  220. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  221. data/yard-stubs/ca_obj_block.rb +73 -0
  222. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  223. data/yard-stubs/ca_obj_fake.rb +31 -0
  224. data/yard-stubs/ca_obj_farray.rb +32 -0
  225. data/yard-stubs/ca_obj_field.rb +45 -0
  226. data/yard-stubs/ca_obj_grid.rb +35 -0
  227. data/yard-stubs/ca_obj_refer.rb +72 -0
  228. data/yard-stubs/ca_obj_roll.rb +45 -0
  229. data/yard-stubs/ca_obj_shift.rb +43 -0
  230. data/yard-stubs/ca_obj_stride.rb +181 -0
  231. data/yard-stubs/ca_obj_tile.rb +29 -0
  232. data/yard-stubs/ca_obj_transpose.rb +40 -0
  233. data/yard-stubs/ca_obj_window.rb +49 -0
  234. data/yard-stubs/carray_access.rb +131 -0
  235. data/yard-stubs/carray_attribute.rb +246 -0
  236. data/yard-stubs/carray_broadcast.rb +37 -0
  237. data/yard-stubs/carray_cast.rb +489 -0
  238. data/yard-stubs/carray_class.rb +65 -0
  239. data/yard-stubs/carray_conversion.rb +76 -0
  240. data/yard-stubs/carray_copy.rb +79 -0
  241. data/yard-stubs/carray_core.rb +114 -0
  242. data/yard-stubs/carray_count.rb +79 -0
  243. data/yard-stubs/carray_element.rb +108 -0
  244. data/yard-stubs/carray_generate.rb +66 -0
  245. data/yard-stubs/carray_lazy.rb +23 -0
  246. data/yard-stubs/carray_loop.rb +140 -0
  247. data/yard-stubs/carray_mask.rb +259 -0
  248. data/yard-stubs/carray_math.rb +132 -0
  249. data/yard-stubs/carray_mathfunc.rb +45 -0
  250. data/yard-stubs/carray_median_percentile.rb +89 -0
  251. data/yard-stubs/carray_memory_view.rb +163 -0
  252. data/yard-stubs/carray_order.rb +312 -0
  253. data/yard-stubs/carray_random.rb +89 -0
  254. data/yard-stubs/carray_scatter.rb +106 -0
  255. data/yard-stubs/carray_slab.rb +57 -0
  256. data/yard-stubs/carray_sort.rb +163 -0
  257. data/yard-stubs/carray_test.rb +85 -0
  258. data/yard-stubs/carray_undef.rb +64 -0
  259. data/yard-stubs/carray_utils.rb +97 -0
  260. data/yard-stubs/ruby_carray.rb +193 -0
  261. metadata +220 -138
  262. data/Rakefile +0 -51
  263. data/TODO.md +0 -18
  264. data/ext/ca_iter_block.c +0 -257
  265. data/ext/ca_iter_dimension.c +0 -299
  266. data/ext/ca_iter_window.c +0 -214
  267. data/ext/ca_obj_mapping.c +0 -644
  268. data/ext/ca_obj_unbound_repeat.c +0 -529
  269. data/ext/carray_iterator.c +0 -641
  270. data/ext/carray_math.rb +0 -850
  271. data/ext/carray_numeric.c +0 -259
  272. data/ext/carray_sort_addr.c +0 -254
  273. data/ext/carray_stat.c +0 -2100
  274. data/ext/carray_stat_proc.rb +0 -1999
  275. data/ext/mkmath.rb +0 -741
  276. data/ext/ruby_ccomplex.c +0 -509
  277. data/ext/ruby_float_func.c +0 -86
  278. data/lib/carray/array.rb +0 -8
  279. data/lib/carray/autoload/autoload_base.rb +0 -19
  280. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  281. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  282. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  283. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  284. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  285. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  286. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  287. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  288. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  289. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  290. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  291. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  292. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  293. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  294. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  295. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  296. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  297. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  298. data/lib/carray/autoload.rb +0 -141
  299. data/lib/carray/basic.rb +0 -191
  300. data/lib/carray/broadcast.rb +0 -101
  301. data/lib/carray/compose.rb +0 -315
  302. data/lib/carray/convert.rb +0 -115
  303. data/lib/carray/info.rb +0 -110
  304. data/lib/carray/io/imagemagick.rb +0 -235
  305. data/lib/carray/mask.rb +0 -102
  306. data/lib/carray/math/histogram.rb +0 -177
  307. data/lib/carray/math/recurrence.rb +0 -93
  308. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  309. data/lib/carray/object/ca_obj_link.rb +0 -50
  310. data/lib/carray/object/ca_obj_pack.rb +0 -99
  311. data/lib/carray/obsolete.rb +0 -256
  312. data/lib/carray/ordering.rb +0 -181
  313. data/lib/carray/testing.rb +0 -51
  314. data/lib/carray/transform.rb +0 -109
  315. data/mailmap +0 -1
  316. data/misc/Methods.ja.md +0 -182
  317. data/misc/NOTE +0 -51
  318. data/spec/Classes/CABitfield_spec.rb +0 -58
  319. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  320. data/spec/Classes/CABlock_spec.rb +0 -205
  321. data/spec/Classes/CAField_spec.rb +0 -39
  322. data/spec/Classes/CAGrid_spec.rb +0 -75
  323. data/spec/Classes/CAMap_spec.rb +0 -0
  324. data/spec/Classes/CAMapping_spec.rb +0 -105
  325. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  326. data/spec/Classes/CAObject_spec.rb +0 -33
  327. data/spec/Classes/CARefer_spec.rb +0 -93
  328. data/spec/Classes/CARepeat_spec.rb +0 -65
  329. data/spec/Classes/CASelect_spec.rb +0 -22
  330. data/spec/Classes/CAShift_spec.rb +0 -16
  331. data/spec/Classes/CAStruct_spec.rb +0 -71
  332. data/spec/Classes/CATranspose_spec.rb +0 -60
  333. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  334. data/spec/Classes/CAWindow_spec.rb +0 -54
  335. data/spec/Classes/CAWrap_spec.rb +0 -8
  336. data/spec/Classes/CArray_spec.rb +0 -184
  337. data/spec/Classes/CScalar_spec.rb +0 -55
  338. data/spec/Features/feature_130_spec.rb +0 -19
  339. data/spec/Features/feature_attributes_spec.rb +0 -280
  340. data/spec/Features/feature_boolean_spec.rb +0 -98
  341. data/spec/Features/feature_broadcast.rb +0 -116
  342. data/spec/Features/feature_cast_function.rb +0 -19
  343. data/spec/Features/feature_cast_spec.rb +0 -33
  344. data/spec/Features/feature_class_spec.rb +0 -84
  345. data/spec/Features/feature_complex_spec.rb +0 -42
  346. data/spec/Features/feature_composite_spec.rb +0 -124
  347. data/spec/Features/feature_convert_spec.rb +0 -46
  348. data/spec/Features/feature_copy_spec.rb +0 -123
  349. data/spec/Features/feature_creation_spec.rb +0 -84
  350. data/spec/Features/feature_element_spec.rb +0 -144
  351. data/spec/Features/feature_extream_spec.rb +0 -54
  352. data/spec/Features/feature_generate_spec.rb +0 -74
  353. data/spec/Features/feature_index_spec.rb +0 -69
  354. data/spec/Features/feature_mask_spec.rb +0 -580
  355. data/spec/Features/feature_math_spec.rb +0 -97
  356. data/spec/Features/feature_order_spec.rb +0 -146
  357. data/spec/Features/feature_ref_store_spec.rb +0 -209
  358. data/spec/Features/feature_serialization_spec.rb +0 -125
  359. data/spec/Features/feature_stat_spec.rb +0 -397
  360. data/spec/Features/feature_virtual_spec.rb +0 -48
  361. data/spec/Features/method_eq_spec.rb +0 -81
  362. data/spec/Features/method_is_nan_spec.rb +0 -12
  363. data/spec/Features/method_map_spec.rb +0 -54
  364. data/spec/Features/method_max_with.rb +0 -20
  365. data/spec/Features/method_min_with.rb +0 -19
  366. data/spec/Features/method_ne_spec.rb +0 -18
  367. data/spec/Features/method_project_spec.rb +0 -188
  368. data/spec/Features/method_ref_spec.rb +0 -27
  369. data/spec/Features/method_round_spec.rb +0 -11
  370. data/spec/Features/method_s_linspace_spec.rb +0 -48
  371. data/spec/Features/method_s_span_spec.rb +0 -14
  372. data/spec/Features/method_seq_spec.rb +0 -47
  373. data/spec/Features/method_sort_with.rb +0 -43
  374. data/spec/Features/method_sorted_with.rb +0 -29
  375. data/spec/Features/method_span_spec.rb +0 -42
  376. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  377. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  378. data/spec/spec_all.rb +0 -10
  379. data/utils/ca_ase.rb +0 -21
  380. data/utils/ca_methods.rb +0 -15
  381. data/utils/cast_checker.rb +0 -30
  382. data/utils/convert_test.rb +0 -73
  383. data/utils/extract_yard.rb +0 -22
  384. data/utils/guess_shape.rb +0 -76
  385. data/utils/monkey_patch_methods.rb +0 -62
  386. data/utils/remove_resource_fork.sh +0 -5
data/ext/carray.h CHANGED
@@ -1,13 +1,3 @@
1
- /* ---------------------------------------------------------------------------
2
-
3
- carray.h
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
8
-
9
- ---------------------------------------------------------------------------- */
10
-
11
1
  #ifndef CARRAY_H
12
2
  #define CARRAY_H
13
3
 
@@ -145,14 +135,11 @@ typedef int8_t boolean8_t;
145
135
  typedef dummy_t float64_t;
146
136
  #endif
147
137
 
148
- /* float128_t is currently disabled in extconf.rb */
149
-
150
- #if HAVE_TYPE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 16
151
- # define HAVE_TYPE_FLOAT128_T 1
152
- typedef long double float128_t;
153
- #else
154
- typedef dummy_t float128_t;
155
- #endif
138
+ /* float128_t / cmplx256_t were retired in carray-3.0 (DROP_LONGDOUBLE).
139
+ The enum slots CA_FLOAT128 (=12) and CA_CMPLX256 (=15) are preserved
140
+ as reserved holes so existing CA_NTYPE-sized tables keep their layout;
141
+ ca_valid[12] and ca_valid[15] are 0, so no user can create a CArray of
142
+ these types. */
156
143
 
157
144
  #ifdef HAVE_COMPLEX_H
158
145
  # include <complex.h>
@@ -172,17 +159,8 @@ typedef int8_t boolean8_t;
172
159
  typedef dummy_t cmplx128_t;
173
160
  #endif
174
161
 
175
- /* cmplx256_t is currently disabled in extconf.rb */
176
-
177
- #if defined(HAVE_TYPE_LONG_DOUBLE_COMPLEX) && SIZEOF_LONG_DOUBLE_COMPLEX == 32
178
- # define HAVE_TYPE_CMPLX256_T 1
179
- typedef long double complex cmplx256_t;
180
- #else
181
- typedef dummy_t cmplx256_t;
182
- #endif
183
-
184
-
185
162
  #include <stddef.h>
163
+ #include <inttypes.h> /* PRId64 for ca_size_t (= int64_t) formatting */
186
164
 
187
165
  #define CA_ALIGN_VOIDP offsetof(struct { char c; void *x; }, x)
188
166
  #define CA_ALIGN_INT8 offsetof(struct { char c; int8_t x; }, x)
@@ -191,10 +169,8 @@ typedef int8_t boolean8_t;
191
169
  #define CA_ALIGN_INT64 offsetof(struct { char c; int64_t x; }, x)
192
170
  #define CA_ALIGN_FLOAT32 offsetof(struct { char c; float32_t x; }, x)
193
171
  #define CA_ALIGN_FLOAT64 offsetof(struct { char c; float64_t x; }, x)
194
- #define CA_ALIGN_FLOAT128 offsetof(struct { char c; float128_t x; }, x)
195
172
  #define CA_ALIGN_CMPLX64 offsetof(struct { char c; cmplx64_t x; }, x)
196
173
  #define CA_ALIGN_CMPLX128 offsetof(struct { char c; cmplx128_t x; }, x)
197
- #define CA_ALIGN_CMPLX256 offsetof(struct { char c; cmplx256_t x; }, x)
198
174
  #define CA_ALIGN_OBJECT offsetof(struct { char c; VALUE x; }, x)
199
175
 
200
176
  /* -------------------------------------------------------------------- */
@@ -204,13 +180,61 @@ typedef int8_t boolean8_t;
204
180
  #define CA_RANK_MAX CA_DIM_MAX
205
181
  #define CA_ATTACH_MAX 0x80000000
206
182
 
183
+ /* Assert an invariant to the optimizer (zero runtime cost). Used to teach
184
+ GCC's value-range propagation facts it cannot derive itself -- chiefly
185
+ `ndim <= CA_RANK_MAX`, which bounds loops and allocations over fixed
186
+ [CA_RANK_MAX] stack arrays. Without this, GCC (11.x) emits false-positive
187
+ -Wstringop-overflow / -Wmaybe-uninitialized / -Walloc-size-larger-than on
188
+ those loops because `int8_t ndim` ranges up to 127 as far as it can see.
189
+ The asserted conditions are hard invariants (CA_CHECK_RANK enforces them at
190
+ array creation); a violation is genuinely unreachable. */
191
+ #if defined(__GNUC__) || defined(__clang__)
192
+ # define CA_ASSUME(cond) do { if ( !(cond) ) __builtin_unreachable(); } while (0)
193
+ #else
194
+ # define CA_ASSUME(cond) ((void)0)
195
+ #endif
196
+
207
197
  #define CA_FLAG_SCALAR 1
208
198
  #define CA_FLAG_MASK_ARRAY 2
209
199
  #define CA_FLAG_VALUE_ARRAY 4
210
200
  #define CA_FLAG_READ_ONLY 8
211
201
  #define CA_FLAG_SHARE_INDEX 16
212
- #define CA_FLAG_NOT_DATA_CLASS 32
202
+ /* bit 32 (formerly CA_FLAG_NOT_DATA_CLASS, removed in 3.0) reused for the
203
+ multi-parent view category (CAStack and any future fan-out view). Generic
204
+ routines that walk a single ->parent test this flag and instead fold over
205
+ the parents[] exposed by the CAMultiParent layout convention. */
206
+ #define CA_FLAG_MULTI_PARENTS 32
213
207
  #define CA_FLAG_CYCLE_CHECK 64
208
+ #define CA_FLAG_IS_FACE 128
209
+ /* Face opt-in ordering/search flags.
210
+ A Face declares that its numeric storage may be descended to for kernel
211
+ dispatch. The two flags are on independent axes -- do not conflate:
212
+ ORDERABLE_STORAGE: storage native order == surface <=> order (self-scope).
213
+ Unlocks sort / sort_addr / sort_index / partition / rank. A unit-bearing
214
+ Face (CATime) is orderable because all elements share the array's
215
+ unit metadata, so storage-direct comparison within self is always right.
216
+ COMPARABLE_STORAGE: an external query may be compared against storage with
217
+ no conversion (cross-scope). Unlocks search / bsearch / find_value_index.
218
+ CATime is ORDERABLE but NOT COMPARABLE: a :s array vs a :ns query
219
+ would silent-wrong under raw int64 compare.
220
+ The gates that read these flags key on CA_FLAG_IS_FACE alone and never look
221
+ at the surface data_type, so a Face whose surface data_type equals its
222
+ numeric storage (a Numeric Face, e.g. CATimedelta) needs them just as much
223
+ as a CA_FIXLEN-surface one: without ORDERABLE it is refused at sort /
224
+ search / count / value-hash entries. Whether COMPARABLE holds is likewise
225
+ not a question of being numeric but of carrying a unit -- CATimedelta is
226
+ int64 on both sides and still sets ORDERABLE only. */
227
+ /* CALazyMarker. A marker layers "read this as the leaf of a lazy chain"
228
+ over storage that is identical to its parent's — the same premise as
229
+ CA_FLAG_IS_FACE — so the two are asked about together wherever a
230
+ storage-identical wrapper has to be seen through. Kept as its own bit
231
+ rather than folded into CA_FLAG_IS_FACE: ca_is_face is read in ~100
232
+ places that mean the Face mechanism specifically. */
233
+ #define CA_FLAG_IS_LAZY_MARKER 1024
234
+
235
+ #define CA_FLAG_FACE_ORDERABLE_STORAGE 256
236
+ #define CA_FLAG_FACE_COMPARABLE_STORAGE 512
237
+ /* NOTE: `flags` is int32_t, so there is plenty of bit space left. */
214
238
 
215
239
  enum {
216
240
  CA_LITTLE_ENDIAN = 0,
@@ -219,7 +243,7 @@ enum {
219
243
 
220
244
  enum {
221
245
  CA_REAL_ARRAY,
222
- CA_VIRTUAL_ARRAY
246
+ CA_VIEW_ARRAY
223
247
  };
224
248
 
225
249
  enum {
@@ -231,7 +255,6 @@ enum {
231
255
  CA_OBJ_SELECT,
232
256
  CA_OBJ_OBJECT,
233
257
  CA_OBJ_REPEAT,
234
- CA_OBJ_UNBOUND_REPEAT,
235
258
  };
236
259
 
237
260
  enum {
@@ -290,46 +313,130 @@ enum {
290
313
  #endif
291
314
 
292
315
  /* -------------------------------------------------------------------- */
316
+ /* Per-axis descriptor framework (D1+D2+D3): types, producer interface,
317
+ and common attach engine. Lives in its own header so the carray.h
318
+ preamble stays focused on basic types + struct definitions. */
319
+ #include "ca_axis_descriptor.h"
320
+
321
+ /* xfer protocol direction flags. The protocol is walked through in
322
+ guides/devel/04_attach_lifecycle.md. */
323
+ #define CA_XFER_GET 0 /* target -> data (gather) */
324
+ #define CA_XFER_PUT 1 /* data -> target (scatter) */
325
+
326
+ /* compose-fold state threaded through ca_stride_compose_to_root.
327
+ strides / base / counts are expressed
328
+ in the *current parent*'s byte space; ndim is invariant through the walk.
329
+ counts[] is the leaf's per-dim extent (== leaf->dim), used by
330
+ ca_stride_compose_through's bounds check and by sometimes-fold
331
+ participants for their per-request fold decision. */
332
+ typedef struct {
333
+ int8_t ndim;
334
+ ca_size_t base;
335
+ ca_size_t strides[CA_RANK_MAX];
336
+ ca_size_t counts[CA_RANK_MAX];
337
+ } ca_fold_t;
293
338
 
294
339
  typedef struct {
295
340
  int32_t obj_type;
296
341
  int32_t entity_type;
297
342
  void (*free_object) (void *ap);
298
343
  void * (*clone) (void *ap);
299
- char * (*ptr_at_addr) (void *ap, ca_size_t addr);
300
- char * (*ptr_at_index) (void *ap, ca_size_t *idx);
301
- void (*fetch_addr) (void *ap, ca_size_t addr, void *data);
302
- void (*fetch_index) (void *ap, ca_size_t *idx, void *data);
303
- void (*store_addr) (void *ap, ca_size_t addr, void *data);
304
- void (*store_index) (void *ap, ca_size_t *idx, void *data);
305
344
  void (*allocate) (void *ap);
306
345
  void (*attach) (void *ap);
307
346
  void (*sync) (void *ap);
308
347
  void (*detach) (void *ap);
309
- void (*copy_data) (void *ap, void *data);
310
- void (*sync_data) (void *ap, void *data);
311
348
  void (*fill_data) (void *ap, void *data);
312
349
  void (*create_mask) (void *ap);
350
+ /* xfer protocol. Added at struct end so existing
351
+ positional initializers leave it NULL automatically. dir = CA_XFER_GET /
352
+ CA_XFER_PUT. */
353
+ void (*xfer_index) (void *ap, ca_size_t *idx, void *data, int dir);
354
+ void (*xfer_addrs) (void *ap, ca_size_t n, ca_size_t *addrs,
355
+ void *data, int dir);
356
+ /* fold_stride: one compose-fold hop
357
+ for sometimes-fold participants (CAWindow now; CAGrid/CSA/CATile later).
358
+ Compose *f into next_parent's byte space and return 1, or decline
359
+ (leave *f / *next_parent untouched) and return 0 -> this view is the
360
+ fold boundary. CAStride family leaves this NULL (handled open-inline
361
+ by ca_stride_compose_to_root). */
362
+ int (*fold_stride) (void *ap, ca_fold_t *f, void **next_parent);
363
+ /* xfer_stride: deliver a region of
364
+ counts[k] cells per axis to/from a caller buffer. Local materialise of
365
+ the requested region only (never the whole view).
366
+
367
+ All three of starts/counts/strides describe the region in *this view's*
368
+ own address space: the first cell is at Sigma starts[k]*native[k] (native =
369
+ this view's row-major byte layout) and successive cells along axis k sit
370
+ strides[k] bytes apart, so strides[k] / native[k] is the index step and
371
+ the region need not be contiguous. `data` is the caller buffer, holding
372
+ the Pi counts[k] selected cells packed row-major -- it is NOT laid out
373
+ with strides[]. dir = CA_XFER_GET / CA_XFER_PUT. */
374
+ void (*xfer_stride) (void *ap, ca_size_t *starts, ca_size_t *counts,
375
+ ca_size_t *strides, void *data, int dir);
376
+ /* xfer_all: whole-view transfer, the direction-unified replacement of
377
+ copy_data / sync_data. Holds the view's optimal whole-domain delivery
378
+ (compose-fold, partial materialise, etc.).
379
+ dir = CA_XFER_GET (gather: view -> data) / CA_XFER_PUT (scatter). */
380
+ void (*xfer_all) (void *ap, void *data, int dir);
381
+ /* Pool framework (guides/devel/03_memory_management.md). Optional;
382
+ unfilled slots leave the obj_type on the legacy ALLOC_N path. When
383
+ populated, framework primitives in ca_array_pool.c manage a single
384
+ contiguous `_pool` buffer that holds dim/strides/<subclass tail>. */
385
+ size_t struct_size; /* sizeof(<concrete struct>) */
386
+ size_t (*pool_bytes) (int8_t ndim); /* required if struct_size != 0 */
387
+ void (*pool_init) (void *ap, int8_t ndim); /* required if struct_size != 0 */
388
+ /* fill_addrs / fill_stride: write one value into part of the view.
389
+ fill_data carries no
390
+ region and so can only say "fill everything I cover"; without a region the
391
+ only way left to fill part of a view was to borrow a pointer, which
392
+ materialises a non-foldable root and writes it all back. `ptr` is a
393
+ single element's worth of bytes, as for fill_data, since the value does
394
+ not scale with the region.
395
+
396
+ fill_stride describes the region over the view's own *linear addresses*:
397
+ `base` is where it starts and steps[k] is the address step along axis k,
398
+ counts[k] axes deep. Addresses rather than an index box because a view
399
+ hands its region to its parent, and the two need not agree on ndim -- a
400
+ dimension-dropping view has no box in its parent's index space. This is
401
+ the shape ca_xfer_stride composes to internally before it walks.
402
+
403
+ Leave NULL to take the per-cell default in ca_fill_addrs / ca_fill_stride. */
404
+ void (*fill_addrs) (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr);
405
+ void (*fill_stride) (void *ap, ca_size_t base, int8_t ndim,
406
+ ca_size_t *counts, ca_size_t *steps, void *ptr);
313
407
  } ca_operation_function_t;
314
408
 
315
409
  /* default operation_function */
316
410
 
317
411
  void * ca_array_func_clone (void *ap);
318
- char * ca_array_func_ptr_at_addr (void *ap, ca_size_t addr);
319
- char * ca_array_func_ptr_at_index (void *ap, ca_size_t *idx);
320
- void ca_array_func_fetch_addr (void *ap, ca_size_t addr, void *ptr);
321
- void ca_array_func_fetch_index (void *ap, ca_size_t *idx, void *ptr);
322
- void ca_array_func_store_addr (void *ap, ca_size_t addr, void *ptr);
323
- void ca_array_func_store_index (void *ap, ca_size_t *idx, void *ptr);
324
412
  void ca_array_func_allocate (void *ap);
325
413
  void ca_array_func_attach (void *ap);
326
414
  void ca_array_func_sync (void *ap);
327
415
  void ca_array_func_detach (void *ap);
328
- void ca_array_func_copy_data (void *ap, void *ptr);
329
- void ca_array_func_sync_data (void *ap, void *ptr);
416
+ void ca_array_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir);
417
+ void ca_array_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
418
+ void *data, int dir);
419
+ void ca_array_func_xfer_all (void *ap, void *data, int dir);
330
420
  void ca_array_func_fill_data (void *ap, void *val);
331
421
  void ca_array_func_create_mask (void *ap);
332
422
 
423
+ /* Pool framework primitives (guides/devel/03_memory_management.md).
424
+ - ca_array_alloc: xmalloc(struct_size) + ca_array_pool_alloc().
425
+ For the C construction path (= replaces
426
+ TypedData_Make_Struct + per-field ALLOC_N).
427
+ - ca_array_pool_alloc: xmalloc(pool_bytes(ndim)) into ca->_pool, then
428
+ run pool_init. For the initialize_copy path
429
+ where TypedData_Make_Struct has already
430
+ allocated the struct. Both fields must be
431
+ registered in ca_func[obj_type].
432
+ - ca_array_free: xfree(ca->_pool) and xfree(ca). Per-class
433
+ free_object callbacks call this branch when
434
+ ca->_pool != NULL; otherwise they fall through
435
+ to the legacy ALLOC_N free path. */
436
+ void * ca_array_alloc (int8_t obj_type, int8_t ndim);
437
+ void ca_array_pool_alloc (void *ap, int8_t obj_type, int8_t ndim);
438
+ void ca_array_free (void *ap);
439
+
333
440
  /* -------------------------------------------------------------------- */
334
441
 
335
442
  /* CArray : base class of all carray object */
@@ -346,6 +453,10 @@ struct _CArray {
346
453
  ca_size_t *dim;
347
454
  char *ptr;
348
455
  CArray *mask;
456
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
457
+ Reserved for framework use; ext authors must not read,
458
+ write, or xfree this field directly. See
459
+ ext/ca_array_pool.c. */
349
460
  }; /* 28 + 4*ndim (bytes) */
350
461
 
351
462
  typedef CArray CAWrap;
@@ -360,6 +471,10 @@ typedef struct {
360
471
  ca_size_t *dim;
361
472
  char *ptr;
362
473
  CArray *mask;
474
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
475
+ Reserved for framework use; ext authors must not read,
476
+ write, or xfree this field directly. See
477
+ ext/ca_array_pool.c. */
363
478
  ca_size_t _dim;
364
479
  } CScalar; /* 32 (bytes) */
365
480
 
@@ -373,11 +488,25 @@ typedef struct {
373
488
  ca_size_t *dim;
374
489
  char *ptr;
375
490
  CArray *mask;
491
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
492
+ Reserved for framework use; ext authors must not read,
493
+ write, or xfree this field directly. See
494
+ ext/ca_array_pool.c. */
376
495
  CArray *parent;
377
496
  uint32_t attach;
378
497
  uint8_t nosync;
379
- } CAVirtual; /* 40 + 4*(ndim) (bytes) */
380
-
498
+ } CAView; /* 40 + 4*(ndim) (bytes) */
499
+
500
+ /* CARefer (Phase C): CAStride prefix + a `mask0` tail.
501
+ - reshape (mode 0/1) and byte-reinterpret (modes ±2) are all
502
+ expressed as a contiguous byte-aligned strided view; differences
503
+ between modes collapse to (strides, base_offset). The previous
504
+ `is_deformed` flag is no longer stored -- it's implied by the
505
+ comparison `ca->bytes vs ca->parent->bytes`.
506
+ - `mask0` owns the CARepeat (divided) or CAReduce (spanned)
507
+ intermediate that the user-visible mask is a refer-of, for the
508
+ byte-reinterpret modes. NULL for simple reshape and for
509
+ parent-without-mask cases. */
381
510
  typedef struct {
382
511
  int16_t obj_type;
383
512
  int8_t data_type;
@@ -388,19 +517,30 @@ typedef struct {
388
517
  ca_size_t *dim;
389
518
  char *ptr;
390
519
  CArray *mask;
520
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
521
+ Reserved for framework use; ext authors must not read,
522
+ write, or xfree this field directly. See
523
+ ext/ca_array_pool.c. */
391
524
  CArray *parent;
392
525
  uint32_t attach;
393
526
  uint8_t nosync;
394
- /* ---------- */
395
- int8_t is_deformed; /* 0 : not deformed */
396
- /* 1 : deformed */
397
- /* -2 : divided */
398
- /* 2 : spanned */
399
- ca_size_t ratio;
400
- ca_size_t offset;
527
+ /* --- CAStride prefix continues --- */
528
+ ca_size_t *strides;
529
+ ca_size_t base_offset;
530
+ /* --- CARefer tail --- */
401
531
  CArray *mask0;
402
- } CARefer; /* 52 + 4*(ndim) (bytes) */
403
-
532
+ } CARefer;
533
+
534
+ /* CABlock (Phase E): CAStride prefix + native-spec tail.
535
+ The tail (offset, start, step, count, size0) is preserved for:
536
+ - public Ruby accessors (#offset, #start, #step, #count, #size0)
537
+ - #idx2addr0 / #addr2addr0 implementations
538
+ - block / dimension iterators that mutate start[] in place
539
+ After every mutation of `start[]`, base_offset must be
540
+ recomputed to stay consistent with the CAStride prefix.
541
+
542
+ The old maxdim_* gather-loop optimization fields are gone:
543
+ CAStride's own gather/scatter (P1/P1.5/P2/P3) does the same job. */
404
544
  typedef struct {
405
545
  int16_t obj_type;
406
546
  int8_t data_type;
@@ -411,19 +551,23 @@ typedef struct {
411
551
  ca_size_t *dim;
412
552
  char *ptr;
413
553
  CArray *mask;
554
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
555
+ Reserved for framework use; ext authors must not read,
556
+ write, or xfree this field directly. See
557
+ ext/ca_array_pool.c. */
414
558
  CArray *parent;
415
559
  uint32_t attach;
416
560
  uint8_t nosync;
417
- /* ---------- */
418
- int8_t maxdim_index;
419
- ca_size_t maxdim_step;
420
- ca_size_t maxdim_step0;
561
+ /* --- CAStride prefix continues --- */
562
+ ca_size_t *strides;
563
+ ca_size_t base_offset;
564
+ /* --- CABlock tail (native spec) --- */
421
565
  ca_size_t offset;
422
566
  ca_size_t *start;
423
567
  ca_size_t *step;
424
568
  ca_size_t *count;
425
569
  ca_size_t *size0;
426
- } CABlock; /* 68 + 20*(ndim) (bytes) */
570
+ } CABlock;
427
571
 
428
572
  typedef struct {
429
573
  int16_t obj_type;
@@ -435,16 +579,17 @@ typedef struct {
435
579
  ca_size_t *dim;
436
580
  char *ptr;
437
581
  CArray *mask;
582
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
583
+ Reserved for framework use; ext authors must not read,
584
+ write, or xfree this field directly. See
585
+ ext/ca_array_pool.c. */
438
586
  CArray *parent;
439
587
  uint32_t attach;
440
588
  uint8_t nosync;
441
589
  /* ---------- */
442
- uint8_t bounds;
443
- ca_size_t *start;
444
- ca_size_t *count;
445
- ca_size_t *size0;
446
- char *fill;
447
- } CAWindow; /* 56 + 16*(ndim) + 1*(bytes) (bytes) */
590
+ ca_size_t *strides; /* byte strides, negative allowed */
591
+ ca_size_t base_offset; /* byte offset from parent->ptr to view[0,...] */
592
+ } CAStride; /* CA_OBJ_STRIDE: generic strided view */
448
593
 
449
594
  typedef struct {
450
595
  int16_t obj_type;
@@ -456,19 +601,63 @@ typedef struct {
456
601
  ca_size_t *dim;
457
602
  char *ptr;
458
603
  CArray *mask;
604
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
605
+ Reserved for framework use; ext authors must not read,
606
+ write, or xfree this field directly. See
607
+ ext/ca_array_pool.c. */
459
608
  CArray *parent;
460
609
  uint32_t attach;
461
610
  uint8_t nosync;
462
- /* -------------*/
463
- CArray *data;
464
- VALUE self;
465
- } CAObject; /* 48 + 4*(ndim) (bytes) */
466
-
467
- /*
468
- CAObjectMask is an internal class
469
- used only as mask array of CAObject.
470
- */
471
-
611
+ /* ---------- */
612
+ uint8_t *bounds; /* [ndim] per-axis policy (a scalar uint8_t
613
+ before). Allows
614
+ CAShift (per-axis roll[]) to be expressed as
615
+ a CAWindow specialisation. */
616
+ ca_size_t *start;
617
+ ca_size_t *count;
618
+ ca_size_t *size0;
619
+ char *fill;
620
+ /* COMPOSITE_FAMILY Phase 1 (E.2): embed descriptor model. Computed by
621
+ ca_compute_embed_descriptor at setup time, immutable for view lifetime.
622
+ Used by attach/sync (E.3-E.4) to skip per-element bound checks via
623
+ "1 alias + 1 fill" decomposition. */
624
+ ca_size_t *embed_parent_start; /* [ndim] parent-side alias rectangle start */
625
+ ca_size_t *embed_count; /* [ndim] alias rectangle size per axis */
626
+ ca_size_t *embed_output_offset; /* [ndim] output-side alias rectangle start */
627
+ uint8_t embed_is_empty; /* 1 = fully out of parent, alias is empty */
628
+ uint8_t embed_covers_all; /* 1 = interior-only, fill is unused */
629
+ uint8_t embed_eligible; /* 1 = all bounds in {FILL, MASK}, attach
630
+ takes the embed fast path (E.3). Other
631
+ policies (PERIODIC/REFLECT/...) fall
632
+ back to the ca_axis_dispatch_* engine. */
633
+ uint8_t embed_alias_eligible; /* 1 = direct ca_attach(window) can alias
634
+ to parent->ptr without copy (Phase 1.5
635
+ E.8 A-path). Condition: embed_eligible
636
+ + embed_covers_all + inner axes full
637
+ (count[k] == parent->dim[k] && start[k]
638
+ == 0 for k >= 1). Embedded region
639
+ must be contig in parent storage. */
640
+ } CAWindow; /* 56 + 16*(ndim) + 1*(bytes) + 1*ndim + 24*ndim (bytes) */
641
+
642
+ /* CAShift is a pure typedef of CAWindow. CAShift construction maps (shift[], roll[], fill,
643
+ fill_mask) onto CAWindow's (start = -shift, count = parent->dim,
644
+ bounds = roll ? PERIODIC : (fill_mask ? MASK : FILL), fill). The
645
+ two views share the operation table (ca_window_func); only obj_type
646
+ differs (CA_OBJ_SHIFT vs CA_OBJ_WINDOW) to preserve user-facing class
647
+ distinction. */
648
+ typedef CAWindow CAShift;
649
+
650
+ /* COMPOSITE_FAMILY Phase 2 (T.3, 2026-05-26): CATile = N-region
651
+ expansion view (tiled repetition of the parent). Output shape =
652
+ parent.dim * reps per axis; total tiles = product(reps). Each tile
653
+ is a full-parent alias at output offset
654
+ (i_0 * parent.dim[0], i_1 * parent.dim[1], ...). Attach iterates
655
+ total_tiles regions, calling ca_composite_region_gather for each.
656
+
657
+ CARoll = typedef CATile (same pattern as the
658
+ CAShift = CAWindow precedent); constructor parameters differ but the
659
+ C struct layout is shared, and the attach/sync routine is identical
660
+ (= dispatch the region list in order). */
472
661
  typedef struct {
473
662
  int16_t obj_type;
474
663
  int8_t data_type;
@@ -479,9 +668,101 @@ typedef struct {
479
668
  ca_size_t *dim;
480
669
  char *ptr;
481
670
  CArray *mask;
482
- /* -------------*/
483
- VALUE array;
484
- } CAObjectMask;
671
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
672
+ Reserved for framework use; ext authors must not read,
673
+ write, or xfree this field directly. See
674
+ ext/ca_array_pool.c. */
675
+ CArray *parent;
676
+ uint32_t attach;
677
+ uint8_t nosync;
678
+ /* ---------- */
679
+ ca_size_t *reps; /* [ndim] number of tiles per axis.
680
+ Total tiles = product(reps).
681
+ dim[k] = parent->dim[k] * reps[k]. */
682
+ } CATile; /* 56 + 8*(ndim) (bytes) */
683
+
684
+ typedef CATile CARoll; /* T.4 will land CARoll-specific constructor +
685
+ obj_type CA_OBJ_ROLL. Until then CARoll path
686
+ is just CATile (= typedef body identical). */
687
+
688
+ /* CAStack: outer-axis-only stack view of K uniform-shape parents. shape = (K, *parent_shape),
689
+ axis 0 maps to parent index, axes 1..ndim-1 are per-parent contig.
690
+ - parents stored as Ruby Array @parents on the wrapper object (= GC
691
+ anchor); C-side tail `parents[]` is alias pointer array.
692
+ - CAView.parent points to parents[0] (= legacy compat for paths that
693
+ deref ca->parent without CAStack awareness).
694
+ - dim[0] = n_parents; dim[1..ndim-1] = parents[0]->dim[0..ndim-2]. */
695
+ typedef struct {
696
+ int16_t obj_type;
697
+ int8_t data_type;
698
+ int8_t ndim; /* = parents[0]->ndim + 1 */
699
+ int32_t flags;
700
+ ca_size_t bytes;
701
+ ca_size_t elements; /* = n_parents * parents[0]->elements */
702
+ ca_size_t *dim; /* ALLOC_N(ndim) = [n_parents, *parent->dim] */
703
+ char *ptr;
704
+ CArray *mask;
705
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
706
+ Reserved for framework use; ext authors must not read,
707
+ write, or xfree this field directly. See
708
+ ext/ca_array_pool.c. */
709
+ CArray *parent; /* = parents[0] (legacy CAView field) */
710
+ uint32_t attach;
711
+ uint8_t nosync;
712
+ /* ---- CAStack tail ---- */
713
+ int32_t n_parents; /* K = axis-0 size */
714
+ CArray **parents; /* ALLOC_N(CArray*, n_parents); aliases, not owned */
715
+ int8_t k_axis; /* K axis insertion position in view shape, [0, parent_ndim].
716
+ 0 = outer-axis stack (legacy default).
717
+ parent_ndim = K innermost (= old merge at=-1).
718
+ Set by ca_stack_setup_with_axis / preserved on clone. */
719
+ } CAStack;
720
+
721
+ /* CAMeld (ragged concatenate view along an existing axis). Unlike CAStack
722
+ which introduces a new K axis, CAMeld welds K parents along one of their
723
+ existing axes and may have uneven segment lengths there.
724
+ shape[a] = parents[0]->dim[a] for a != meld_axis
725
+ shape[meld_axis] = sum_k parents[k]->dim[meld_axis]
726
+ All other axes must match across parents (uniform check at constructor).
727
+
728
+ v0.1 stub: external-axis (meld_axis == 0) structural xfer_stride path only.
729
+ Other paths raise NotImplementedError. */
730
+ typedef struct {
731
+ int16_t obj_type;
732
+ int8_t data_type;
733
+ int8_t ndim; /* = parents[0]->ndim (no new axis) */
734
+ int32_t flags;
735
+ ca_size_t bytes;
736
+ ca_size_t elements; /* = sum_k parents[k]->elements */
737
+ ca_size_t *dim; /* ALLOC_N(ndim); dim[meld_axis]=seg_offset[K], else parents[0]->dim */
738
+ char *ptr;
739
+ CArray *mask;
740
+ char *_pool; /* framework-managed pool buffer; do not touch */
741
+ CArray *parent; /* = parents[0] (legacy CAView field) */
742
+ uint32_t attach;
743
+ uint8_t nosync;
744
+ /* ---- CAMeld tail (n_parents / parents kept adjacent to header for
745
+ CAMultiParent layout convention) ---- */
746
+ int32_t n_parents; /* K = number of segments */
747
+ CArray **parents; /* ALLOC_N(CArray*, K); aliases, not owned */
748
+ int8_t meld_axis; /* existing axis being welded, [0, parent_ndim) */
749
+ ca_size_t *seg_offset; /* ALLOC_N(ca_size_t, K+1); prefix sum along meld_axis.
750
+ seg_offset[0]=0, seg_offset[k+1]=seg_offset[k]+parents[k]->dim[meld_axis],
751
+ seg_offset[K]=dim[meld_axis]. */
752
+ } CAMeld;
753
+
754
+ /* Multi-parent view layout convention (CA_FLAG_MULTI_PARENTS). A view that
755
+ fans out to K parents must place `n_parents` + `parents[]` immediately after
756
+ the CAView header (exactly as CAStack does) so generic routines that would
757
+ otherwise walk a single ->parent can fold over all parents without knowing
758
+ the concrete view type. Cast `(CAMultiParent *) ca` only when the flag is
759
+ set. CAStack is the first conforming type (layout-checked in
760
+ Init_ca_obj_stack via offsetof). */
761
+ typedef struct {
762
+ CAView header; /* common view prefix (obj_type .. nosync) */
763
+ int32_t n_parents;
764
+ CArray **parents;
765
+ } CAMultiParent;
485
766
 
486
767
  typedef struct {
487
768
  int16_t obj_type;
@@ -493,16 +774,22 @@ typedef struct {
493
774
  ca_size_t *dim;
494
775
  char *ptr;
495
776
  CArray *mask;
777
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
778
+ Reserved for framework use; ext authors must not read,
779
+ write, or xfree this field directly. See
780
+ ext/ca_array_pool.c. */
496
781
  CArray *parent;
497
782
  uint32_t attach;
498
783
  uint8_t nosync;
499
784
  /* -------------*/
500
- ca_size_t *count;
501
- ca_size_t repeat_level;
502
- ca_size_t repeat_num;
503
- ca_size_t contig_level;
504
- ca_size_t contig_num;
505
- } CARepeat; /* 60 + 8*(ndim) (bytes) */
785
+ CArray *data;
786
+ VALUE self;
787
+ } CAObject; /* 48 + 4*(ndim) (bytes) */
788
+
789
+ /*
790
+ CAObjectMask is an internal class
791
+ used only as mask array of CAObject.
792
+ */
506
793
 
507
794
  typedef struct {
508
795
  int16_t obj_type;
@@ -514,13 +801,17 @@ typedef struct {
514
801
  ca_size_t *dim;
515
802
  char *ptr;
516
803
  CArray *mask;
517
- CArray *parent;
518
- uint32_t attach;
519
- uint8_t nosync;
804
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
805
+ Reserved for framework use; ext authors must not read,
806
+ write, or xfree this field directly. See
807
+ ext/ca_array_pool.c. */
520
808
  /* -------------*/
521
- int8_t rep_ndim;
522
- ca_size_t *rep_dim;
523
- } CAUnboundRepeat; /* 44 + 8*(ndim) (bytes) */
809
+ VALUE array;
810
+ } CAObjectMask;
811
+
812
+ /* CARepeat (Phase R migration): structurally identical to CAStride.
813
+ The "repeat" axes are encoded as strides[k] == 0. */
814
+ typedef CAStride CARepeat;
524
815
 
525
816
  /*
526
817
  CAReduce is an internal class
@@ -537,6 +828,10 @@ typedef struct {
537
828
  ca_size_t *dim;
538
829
  char *ptr;
539
830
  CArray *mask;
831
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path).
832
+ Reserved for framework use; ext authors must not read,
833
+ write, or xfree this field directly. See
834
+ ext/ca_array_pool.c. */
540
835
  CArray *parent;
541
836
  uint32_t attach;
542
837
  uint8_t nosync;
@@ -547,15 +842,8 @@ typedef struct {
547
842
 
548
843
  /* -------------------------------------------------------------------- */
549
844
 
550
- typedef struct {
551
- int8_t ndim;
552
- ca_size_t dim[CA_RANK_MAX];
553
- CArray *reference;
554
- CArray * (*kernel_at_addr)(void *, ca_size_t, CArray *);
555
- CArray * (*kernel_at_index)(void *, ca_size_t *, CArray *);
556
- CArray * (*kernel_move_to_addr)(void *, ca_size_t, CArray *);
557
- CArray * (*kernel_move_to_index)(void *, ca_size_t *, CArray *);
558
- } CAIterator;
845
+ /* CAIterator is a form-only Ruby base (see ext/carray_iterator.c); the 2.0 C
846
+ struct (a kernel_at_addr dispatch slot) was retired in 3.0. */
559
847
 
560
848
  /* -------------------------------------------------------------------- */
561
849
 
@@ -566,6 +854,31 @@ extern const char * ca_type_name[CA_NTYPE];
566
854
  extern const int ca_cast_table[CA_NTYPE][CA_NTYPE];
567
855
  extern const int ca_cast_table2[CA_NTYPE][CA_NTYPE];
568
856
 
857
+ /* data_type promotion reducer — pure function over ca_cast_table. Used by
858
+ CArray.result_type and by the lazy view layer. See ext/carray_cast.c
859
+ for the definition; this is the single source of the promotion rule. */
860
+ int8_t ca_promote_type (int8_t a, int8_t b);
861
+
862
+ /* Infer a data_type code from a Ruby *value* (literal Numeric, true/false,
863
+ Complex, etc.) — distinct from rb_ca_guess_type which interprets the
864
+ object as a data_type *representation* (e.g. T_FIXNUM as a data_type code).
865
+ Used by then_else and by ca_lazy_wrap_scalar's bool-self corner case.
866
+ CArray is not accepted (callers should use ca->data_type directly). */
867
+ int8_t ca_value_to_data_type (VALUE obj);
868
+
869
+ /* Infer a data_type code from a MemoryView producer by parsing its format,
870
+ without importing the data. Returns -1 when obj is not an MV producer or
871
+ its format is not representable, so the caller falls back to value inference.
872
+ Defined in ext/carray_memory_view.c. */
873
+ int8_t ca_mv_probe_data_type (VALUE obj);
874
+
875
+ /* Symbol cache for data_type code → Symbol lookup. Initialized in
876
+ Init_carray_class. Indexed by data_type code (0 = CA_FIXLEN ...
877
+ CA_NTYPE-1 = CA_OBJECT). Use rb_ca_data_type_to_sym for the public
878
+ conversion entry point (it validates the code first). */
879
+ extern ID ca_data_type_sym[CA_NTYPE];
880
+ VALUE rb_ca_data_type_to_sym (int8_t data_type);
881
+
569
882
  extern VALUE ca_class[CA_OBJ_TYPE_MAX];
570
883
  extern const rb_data_type_t *ca_typeddata[CA_OBJ_TYPE_MAX];
571
884
  extern VALUE ca_mask_class[CA_OBJ_TYPE_MAX];
@@ -573,35 +886,42 @@ extern const rb_data_type_t *ca_mask_typeddata[CA_OBJ_TYPE_MAX];
573
886
  extern ca_operation_function_t ca_func[CA_OBJ_TYPE_MAX];
574
887
  extern int ca_obj_num;
575
888
 
576
- #define CAVIRTUAL(x) ((CAVirtual *)(x))
889
+ #define CAVIEW(x) ((CAView *)(x))
577
890
 
578
- #define ca_set_flag(ca, flag) ( ca->flags |= flag )
579
- #define ca_unset_flag(ca, flag) ( ca->flags &= ~flag )
580
- #define ca_test_flag(ca, flag) (( ca->flags & flag ) ? 1 : 0)
891
+ /* CAREFUL: `flag` is parenthesised. Without it, ca_test_flag(ca, A | B)
892
+ expands to `ca->flags & A | B`, and since & binds tighter than | the
893
+ test is true for every array. ca_unset_flag had the mirror hazard
894
+ through ~. */
895
+ #define ca_set_flag(ca, flag) ( (ca)->flags |= (flag) )
896
+ #define ca_unset_flag(ca, flag) ( (ca)->flags &= ~(flag) )
897
+ #define ca_test_flag(ca, flag) (( (ca)->flags & (flag) ) ? 1 : 0)
581
898
 
582
899
  /* -------------------------------------------------------------------- */
583
900
 
584
- extern const rb_data_type_t caiterator_data_type;
585
-
586
901
  extern const rb_data_type_t carray_data_type;
587
902
  extern const rb_data_type_t cawrap_data_type;
588
903
  extern const rb_data_type_t cscalar_data_type;
589
- extern const rb_data_type_t cavirtual_data_type;
904
+ extern const rb_data_type_t caview_data_type;
905
+ extern const rb_data_type_t caface_data_type;
906
+ extern const rb_data_type_t casource_data_type;
590
907
 
591
908
  extern const rb_data_type_t cabitarray_data_type;
592
909
  extern const rb_data_type_t cabitfield_data_type;
593
910
  extern const rb_data_type_t cablock_data_type;
911
+ extern const rb_data_type_t castride_data_type;
912
+ extern const rb_data_type_t castride_mask_data_type;
594
913
  extern const rb_data_type_t cafake_data_type;
595
- extern const rb_data_type_t cafield_data_type;
914
+ extern const rb_data_type_t cabyteswap_data_type;
915
+ /* cafield_data_type was retired in 3.0 (Phase F: CAField is now a
916
+ CAStride subclass; use castride_data_type). */
596
917
  extern const rb_data_type_t cagrid_data_type;
597
- extern const rb_data_type_t camapping_data_type;
918
+ /* camapping_data_type was retired in 3.0 (R.3: CAMapping removed; a[mapper]
919
+ now builds a CAGrid/CAStride normalize chain). */
598
920
  extern const rb_data_type_t caobject_data_type;
599
921
  extern const rb_data_type_t careduce_data_type;
600
922
  extern const rb_data_type_t carefer_data_type;
601
- extern const rb_data_type_t carepeat_data_type;
602
923
  extern const rb_data_type_t caselect_data_type;
603
924
  extern const rb_data_type_t cashift_data_type;
604
- extern const rb_data_type_t catrans_data_type;
605
925
  extern const rb_data_type_t caunboundrepeat_data_type;
606
926
  extern const rb_data_type_t cawindow_data_type;
607
927
 
@@ -611,34 +931,37 @@ extern const rb_data_type_t cagrid_mask_data_type;
611
931
  extern const rb_data_type_t camapping_mask_data_type;
612
932
  extern const rb_data_type_t careduce_mask_data_type;
613
933
  extern const rb_data_type_t carefer_mask_data_type;
614
- extern const rb_data_type_t carepeat_mask_data_type;
615
934
  extern const rb_data_type_t caselect_mask_data_type;
616
935
  extern const rb_data_type_t cashift_mask_data_type;
617
- extern const rb_data_type_t catrans_mask_data_type;
618
936
  extern const rb_data_type_t caunboundrepeat_mask_data_type;
619
937
  extern const rb_data_type_t cawindow_mask_data_type;
620
938
 
621
939
  /* -------------------------------------------------------------------- */
622
940
 
623
941
  extern VALUE rb_cCArray;
624
- extern VALUE rb_cCAVirtual;
942
+ extern VALUE rb_cCAView;
943
+ extern VALUE rb_cCAFace;
944
+ extern VALUE rb_cCASource;
625
945
  extern VALUE rb_cCScalar;
626
946
  extern VALUE rb_cCAWrap;
627
947
  extern VALUE rb_cCARefer;
628
948
  extern VALUE rb_cCABlock;
949
+ extern VALUE rb_cCAField;
950
+ extern VALUE rb_cCAByteSwap;
951
+ extern VALUE rb_cCAStride;
952
+ extern VALUE rb_cCAStrideMask;
629
953
  extern VALUE rb_cCASelect;
630
954
  extern VALUE rb_cCAObject;
631
955
  extern VALUE rb_cCARepeat;
632
- extern VALUE rb_cCAUnboundRepeat;
633
956
  extern VALUE rb_cCAIterator;
634
957
 
635
958
  extern VALUE rb_cCArrayMask;
636
959
  extern VALUE rb_cCAReferMask;
637
960
  extern VALUE rb_cCABlockMask;
961
+ extern VALUE rb_cCAFieldMask;
638
962
  extern VALUE rb_cCASelectMask;
639
963
  extern VALUE rb_cCAObjectMask;
640
964
  extern VALUE rb_cCARepeatMask;
641
- extern VALUE rb_cCAUnboundRepeatMask;
642
965
 
643
966
  extern VALUE rb_mCA;
644
967
  extern VALUE rb_mCAMath;
@@ -655,21 +978,21 @@ extern VALUE rb_cCArrayInt32;
655
978
  extern VALUE rb_cCArrayInt64;
656
979
  extern VALUE rb_cCArrayFloat32;
657
980
  extern VALUE rb_cCArrayFloat64;
658
- extern VALUE rb_cCArrayFloat128;
659
981
  extern VALUE rb_cCArrayCmplx64;
660
982
  extern VALUE rb_cCArrayCmplx128;
661
- extern VALUE rb_cCArrayCmplx256;
662
983
  extern VALUE rb_cCArrayObject;
663
984
 
664
985
  /* -------------------------------------------------------------------- */
665
986
 
666
987
  #define CA_CHECK_DATA_TYPE(data_type) \
667
- if ( data_type <= CA_NONE || data_type >= CA_NTYPE ) { \
668
- rb_raise(rb_eRuntimeError, "invalid data_type id %i", data_type); \
669
- } \
670
- if ( ! ca_valid[data_type] ) { \
671
- rb_raise(rb_eRuntimeError, "data_type %s is disabled", ca_type_name[data_type]); \
672
- }
988
+ do { \
989
+ if ( data_type <= CA_NONE || data_type >= CA_NTYPE ) { \
990
+ rb_raise(rb_eRuntimeError, "invalid data_type id %i", data_type); \
991
+ } \
992
+ if ( ! ca_valid[data_type] ) { \
993
+ rb_raise(rb_eRuntimeError, "data_type %s is disabled", ca_type_name[data_type]); \
994
+ } \
995
+ } while (0)
673
996
 
674
997
  #define CA_CHECK_DATA_TYPE_NUMERIC(data_type) \
675
998
  if ( data_type <= CA_NONE || data_type >= CA_NTYPE || !ca_valid[data_type] || data_type == CA_FIXLEN || data_type == CA_OBJECT ) { \
@@ -702,15 +1025,17 @@ extern VALUE rb_cCArrayObject;
702
1025
  if ( bytes <= 0 ) { \
703
1026
  rb_raise(rb_eRuntimeError, "invalid bytes"); \
704
1027
  } \
705
- }
1028
+ }
706
1029
 
707
1030
  #define CA_CHECK_INDEX(index, dim) \
708
- if ( index < 0 ) { \
709
- index += (dim); \
710
- } \
711
- if ( index < 0 || index >= (dim) ) { \
712
- rb_raise(rb_eIndexError, "index out of range ( %lld <=> 0..%lld )", (ca_size_t) index, (ca_size_t) dim-1); \
713
- }
1031
+ do { \
1032
+ if ( index < 0 ) { \
1033
+ index += (dim); \
1034
+ } \
1035
+ if ( index < 0 || index >= (dim) ) { \
1036
+ rb_raise(rb_eIndexError, "index out of range ( %" PRId64 " <=> 0..%" PRId64 " )", (int64_t) index, (int64_t) dim-1); \
1037
+ } \
1038
+ } while (0)
714
1039
 
715
1040
  #define CA_CHECK_BOUND(ca, idx) \
716
1041
  { \
@@ -724,24 +1049,62 @@ extern VALUE rb_cCArrayObject;
724
1049
 
725
1050
  /* -------------------------------------------------------------------- */
726
1051
 
727
- /* class CComplex */
1052
+ /* complex <-> Ruby Complex conversion
1053
+ (NUM2CC / CC2NUM kept as names for diff minimisation; the legacy
1054
+ CComplex class is gone in 3.0 -- the macros now produce and consume
1055
+ Ruby's built-in Complex.) */
728
1056
 
729
1057
  #ifdef HAVE_COMPLEX_H
730
- extern VALUE rb_cCComplex;
731
- double complex rb_num2cc(VALUE num);
732
- VALUE rb_ccomplex_new (double complex c);
733
- VALUE rb_ccomplex_new2 (double re, double im);
734
- # define NUM2CC rb_num2cc
735
- # define CC2NUM rb_ccomplex_new
1058
+
1059
+ /* CMPLX(re, im) builds a complex from its two parts without going through
1060
+ "re + I * im". That expression evaluates I * im first, so an im of +0.0
1061
+ yields (0.0 + 0.0i) and adding it to a re of -0.0 gives +0.0: the sign of
1062
+ a negative zero real part is lost. The sign matters -- branch cuts are
1063
+ selected by the sign of a zero (log(-1+0i) = +pi*i, log(-1-0i) = -pi*i).
1064
+ CMPLX is C11; provide it when the toolchain predates that. */
1065
+ #ifndef CMPLX
1066
+ # if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
1067
+ # define CMPLX(re, im) __builtin_complex((double)(re), (double)(im))
1068
+ # else
1069
+ # define CMPLX(re, im) \
1070
+ (((union { double _parts[2]; double complex _value; }) \
1071
+ { { (double)(re), (double)(im) } })._value)
1072
+ # endif
1073
+ #endif
1074
+
1075
+ static inline double complex
1076
+ rb_carray_num2cmplx (VALUE num)
1077
+ {
1078
+ if ( RB_TYPE_P(num, T_COMPLEX) ) {
1079
+ return CMPLX(NUM2DBL(rb_complex_real(num)), NUM2DBL(rb_complex_imag(num)));
1080
+ }
1081
+ if ( RB_FLOAT_TYPE_P(num) || RB_INTEGER_TYPE_P(num) ) {
1082
+ return (double complex) NUM2DBL(num);
1083
+ }
1084
+ if ( rb_respond_to(num, rb_intern("to_c")) ) {
1085
+ VALUE c = rb_funcall(num, rb_intern("to_c"), 0);
1086
+ return CMPLX(NUM2DBL(rb_complex_real(c)), NUM2DBL(rb_complex_imag(c)));
1087
+ }
1088
+ if ( rb_respond_to(num, rb_intern("to_f")) ) {
1089
+ return (double complex) NUM2DBL(rb_funcall(num, rb_intern("to_f"), 0));
1090
+ }
1091
+ rb_raise(rb_eTypeError, "can not convert to complex");
1092
+ }
1093
+
1094
+ static inline VALUE
1095
+ rb_carray_cmplx2num (double complex c)
1096
+ {
1097
+ return rb_complex_new(rb_float_new(creal(c)), rb_float_new(cimag(c)));
1098
+ }
1099
+
1100
+ # define NUM2CC rb_carray_num2cmplx
1101
+ # define CC2NUM rb_carray_cmplx2num
1102
+
736
1103
  #else
737
- # define rb_ccomplex_new(c) \
738
- (rb_raise(rb_eRuntimeError, "CComplex not defined"), Qnil)
739
- # define rb_ccomplex_new2(re,im) \
740
- (rb_raise(rb_eRuntimeError, "CComplex not defined"), Qnil)
741
1104
  # define NUM2CC(n) \
742
- (rb_raise(rb_eRuntimeError, "CComplex not defined"), 0)
1105
+ (rb_raise(rb_eRuntimeError, "complex not supported on this build"), 0)
743
1106
  # define CC2NUM(c) \
744
- (rb_raise(rb_eRuntimeError, "CComplex not defined"), Qnil)
1107
+ (rb_raise(rb_eRuntimeError, "complex not supported on this build"), Qnil)
745
1108
  #endif
746
1109
 
747
1110
  VALUE BOOL2OBJ (boolean8_t x);
@@ -759,6 +1122,16 @@ unsigned long long rb_obj2ull (VALUE);
759
1122
 
760
1123
  double OBJ2DBL (VALUE v);
761
1124
 
1125
+ /* Mask-aware object->numeric parsers: return 1 with *out set on success, or
1126
+ 0 (no value; caller masks the cell) on parse failure. Used by the
1127
+ object->int/float cast loop so an unparseable cell becomes UNDEF instead
1128
+ of a silent 0.0 (float) or a raise (int). See ext/carray_cast.c. */
1129
+ int ca_obj2dbl_ok (VALUE v, double *out);
1130
+ int rb_obj2long_ok (VALUE v, long *out);
1131
+ int rb_obj2ulong_ok (VALUE v, unsigned long *out);
1132
+ int rb_obj2ll_ok (VALUE v, long long *out);
1133
+ int rb_obj2ull_ok (VALUE v, unsigned long long *out);
1134
+
762
1135
  /* -------------------------------------------------------------------- */
763
1136
 
764
1137
  /* index parsing */
@@ -777,7 +1150,6 @@ enum {
777
1150
  CA_REG_GRID,
778
1151
  CA_REG_MAPPING,
779
1152
  CA_REG_METHOD_CALL,
780
- CA_REG_UNBOUND_REPEAT,
781
1153
  CA_REG_MEMBER,
782
1154
  CA_REG_ATTRIBUTE,
783
1155
  }; /* CA_REGION_TYPE */
@@ -816,42 +1188,12 @@ typedef struct {
816
1188
 
817
1189
  /* -------------------------------------------------------------------- */
818
1190
 
819
- typedef void (*ca_monop_func_t)(ca_size_t n, boolean8_t *m,
820
- char *ptr1, ca_size_t i1,
821
- char *ptr2, ca_size_t i2);
822
- typedef void (*ca_binop_func_t)(ca_size_t n, boolean8_t *m,
823
- char *ptr1, ca_size_t i1,
824
- char *ptr2, ca_size_t i2,
825
- char *ptr3, ca_size_t i3);
826
- typedef void (*ca_moncmp_func_t)(ca_size_t n, boolean8_t *m,
827
- char *ptr1, ca_size_t i1,
828
- boolean8_t *ptr2, ca_size_t i2);
829
- typedef void (*ca_bincmp_func_t)(ca_size_t n, boolean8_t *m,
830
- char *ptr1, ca_size_t b1, ca_size_t i1,
831
- char *ptr2, ca_size_t b2, ca_size_t i2,
832
- char *ptr3, ca_size_t b3, ca_size_t i3);
833
-
834
- VALUE rb_ca_call_monop (VALUE self, ca_monop_func_t func[]);
835
- VALUE rb_ca_call_monop_bang (VALUE self, ca_monop_func_t func[]);
836
- VALUE rb_ca_call_binop (VALUE self, VALUE other, ca_binop_func_t func[]);
837
- VALUE rb_ca_call_binop_bang (VALUE self, VALUE other, ca_binop_func_t func[]);
838
- VALUE rb_ca_call_moncmp (VALUE self, ca_moncmp_func_t func[]);
839
- VALUE rb_ca_call_bincmp (VALUE self, VALUE other, ca_bincmp_func_t func[]);
840
- void ca_monop_not_implement(ca_size_t n, boolean8_t *m,
841
- char *ptr1, ca_size_t i1,
842
- char *ptr2, ca_size_t i2) __attribute__((noreturn));
843
- void ca_binop_not_implement(ca_size_t n, boolean8_t *m,
844
- char *ptr1, ca_size_t i1,
845
- char *ptr2, ca_size_t i2,
846
- char *ptr3, ca_size_t i3) __attribute__((noreturn));
847
- void ca_moncmp_not_implement(ca_size_t n, boolean8_t *m,
848
- char *ptr1, ca_size_t i1,
849
- boolean8_t *ptr2, ca_size_t i2) __attribute__((noreturn));
850
- void ca_bincmp_not_implement(ca_size_t n, boolean8_t *m,
851
- char *ptr1, ca_size_t b1, ca_size_t i1,
852
- char *ptr2, ca_size_t b2, ca_size_t i2,
853
- char *ptr3, ca_size_t b3, ca_size_t i3) __attribute__((noreturn));
854
- VALUE ca_math_call (VALUE mod, VALUE arg, ID id);
1191
+ /* The element-wise kernel typedefs (ca_monop_func_t / ca_binop_func_t /
1192
+ ca_triop_func_t / ca_moncmp_func_t / ca_bincmp_func_t), the rb_ca_call_*
1193
+ drivers, ca_math_call, and the per-data_type dispatch tables now live in
1194
+ carray_math_kernel.h, which this header
1195
+ includes at the bottom (umbrella). Declarations only moved — definitions
1196
+ and ABI are unchanged. */
855
1197
 
856
1198
  /* -------------------------------------------------------------------- */
857
1199
 
@@ -881,6 +1223,45 @@ VALUE rb_carray_new (int8_t data_type,
881
1223
  VALUE rb_carray_new_safe (int8_t data_type,
882
1224
  int8_t ndim, ca_size_t *dim, ca_size_t bytes, CArray *mask);
883
1225
 
1226
+ /* Create an entity that adopts (takes ownership of) a caller-provided
1227
+ data buffer instead of allocating its own -- for C extensions that
1228
+ already hold a freshly decoded buffer and want to avoid a copy. The
1229
+ buffer must be ruby_xmalloc()'d and at least elements*bytes long; it
1230
+ is freed with xfree() when the array is collected. data_type must not
1231
+ be CA_OBJECT. */
1232
+ CArray *carray_new_adopt (int8_t data_type,
1233
+ int8_t ndim, ca_size_t *dim, ca_size_t bytes, char *ptr);
1234
+ VALUE rb_carray_new_adopt (int8_t data_type,
1235
+ int8_t ndim, ca_size_t *dim, ca_size_t bytes, char *ptr);
1236
+
1237
+ /* Capstone helper: allocate
1238
+ a reduction-output CArray for kernel_iterator authors. Computes
1239
+ output shape = self.dim with slab axes removed (ascending order),
1240
+ collapses to shape [1] when fully reduced. See
1241
+ ext/carray_core.c for docstring + semantics. */
1242
+ VALUE rb_ca_new_reduced (VALUE self, int8_t *slab_axes,
1243
+ int8_t naxes, int32_t data_type, int keep_axis);
1244
+ /* Same shape computation, but the output byte width is passed explicitly
1245
+ so a runtime-width output data_type (CA_FIXLEN) can be allocated. */
1246
+ VALUE rb_ca_new_reduced_bytes (VALUE self, int8_t *slab_axes, int8_t naxes,
1247
+ int32_t data_type, ca_size_t bytes, int keep_axis);
1248
+
1249
+ /* Capstone helper: parse
1250
+ variadic axis argv into validated int8_t array. Accepts Integer
1251
+ args or a single Array arg, normalises negative axes (Python-style),
1252
+ range / duplicate / overflow checks all raise ArgumentError.
1253
+ Returns the validated naxes. */
1254
+ int8_t rb_ca_parse_reduce_axes (int argc, VALUE *argv,
1255
+ CArray *ca, int8_t *out_axes);
1256
+
1257
+ /* Kwarg form: caller extracts axis: kwarg via rb_scan_args + rb_get_kwargs
1258
+ and passes the raw VALUE here. Accepts Qnil/Qundef (= full reduction),
1259
+ Integer (= single axis), or Array of Integer (= multi axes in input
1260
+ order). Validation identical to rb_ca_parse_reduce_axes; raises
1261
+ TypeError on other input. */
1262
+ int8_t rb_ca_parse_reduce_axes_kw (VALUE axis_val,
1263
+ CArray *ca, int8_t *out_axes);
1264
+
884
1265
  VALUE rb_ca_wrap_new (int8_t data_type,
885
1266
  int8_t ndim, ca_size_t *dim, ca_size_t bytes, CArray *mask, char *ptr);
886
1267
 
@@ -905,80 +1286,94 @@ CARefer *ca_refer_new (CArray *ca,
905
1286
  VALUE rb_ca_refer_new (VALUE self,
906
1287
  int8_t data_type, int8_t ndim, ca_size_t *dim,
907
1288
  ca_size_t bytes, ca_size_t offset);
1289
+ VALUE rb_ca_reshape (int argc, VALUE *argv, VALUE self);
1290
+ VALUE rb_ca_flatten (VALUE self);
908
1291
 
909
1292
  /* --- ca_obj_farray.c --- */
910
1293
 
911
1294
  VALUE rb_ca_farray (VALUE self);
912
1295
 
913
- /* --- ca_obj_block.c --- */
914
-
915
- CABlock *ca_block_new (CArray *carray,
916
- int8_t ndim, ca_size_t *dim,
917
- ca_size_t *start, ca_size_t *step, ca_size_t *count,
918
- ca_size_t offset);
919
- VALUE rb_ca_block_new (VALUE cary, int8_t ndim, ca_size_t *dim,
920
- ca_size_t *start, ca_size_t *step, ca_size_t *count,
921
- ca_size_t offset);
922
-
923
- /* --- ca_obj_select.c --- */
924
-
925
- VALUE rb_ca_select_new (VALUE cary, VALUE select);
926
- VALUE rb_ca_select_new_share (VALUE cary, VALUE select);
1296
+ /* --- ca_obj_stride.c --- */
1297
+
1298
+ int ca_stride_setup (CAStride *ca, int8_t obj_type, CArray *parent,
1299
+ int8_t data_type, ca_size_t bytes,
1300
+ int8_t ndim, ca_size_t *dim,
1301
+ ca_size_t *strides, ca_size_t base_offset);
1302
+ CAStride *ca_stride_new (int8_t obj_type, CArray *parent,
1303
+ int8_t data_type, ca_size_t bytes,
1304
+ int8_t ndim, ca_size_t *dim,
1305
+ ca_size_t *strides, ca_size_t base_offset);
1306
+ VALUE rb_ca_stride_new (VALUE cary,
1307
+ int8_t data_type, ca_size_t bytes,
1308
+ int8_t ndim, ca_size_t *dim,
1309
+ ca_size_t *strides, ca_size_t base_offset);
1310
+ extern int8_t CA_OBJ_STRIDE;
1311
+ void ca_stride_compose_to_root (CAStride *leaf,
1312
+ CArray **out_root,
1313
+ ca_size_t *out_strides,
1314
+ ca_size_t *out_base);
1315
+ /* one stride-composition hop: express leaf (in parent's byte space) into
1316
+ parent->parent's byte space. Non-static so sometimes-fold participants
1317
+ (e.g. CAWindow::fold_stride) can compose through a synthetic stride layer. */
1318
+ int ca_stride_compose_through (CAStride *leaf, CAStride *parent,
1319
+ ca_size_t *out_strides, ca_size_t *out_base);
927
1320
 
928
1321
  /* --- ca_obj_grid.c --- */
929
1322
 
930
- VALUE rb_ca_grid_new (VALUE cary, ca_size_t *dim, CArray **grid);
1323
+ /* rb_ca_grid_new signature
1324
+ changed to take a per-axis cag_axis_t proto array (private to
1325
+ ca_obj_grid.c). No external callers exist so the declaration is
1326
+ removed from the public header. */
931
1327
  VALUE rb_ca_grid (int argc, VALUE *argv, VALUE self);
1328
+ int rb_ca_select_axis_eligible_p (int argc, VALUE *argv, VALUE self);
1329
+ VALUE rb_ca_select_axis (int argc, VALUE *argv, VALUE self);
932
1330
 
933
1331
  /* --- ca_obj_mapping.c --- */
934
1332
 
935
- VALUE rb_ca_mapping_new (VALUE cary, CArray *mapper);
936
1333
  VALUE rb_ca_mapping (int argc, VALUE *argv, VALUE self);
937
1334
 
938
1335
  /* --- ca_obj_field.c --- */
939
1336
 
940
- VALUE rb_ca_field_new (VALUE cary,
941
- ca_size_t offset, int8_t data_type, ca_size_t bytes);
942
1337
  VALUE rb_ca_field (int argc, VALUE *argv, VALUE self);
943
1338
 
944
1339
  /* --- ca_obj_fake.c --- */
945
1340
 
946
- VALUE rb_ca_fake_new (VALUE cary, int8_t data_type, ca_size_t bytes);
947
1341
  VALUE rb_ca_fake_type (VALUE self, VALUE rtype, VALUE rbytes);
948
1342
 
949
1343
  /* --- ca_obj_repeat.c --- */
950
1344
 
951
- CARepeat *ca_repeat_new (CArray *carray, int8_t ndim, ca_size_t *count);
952
-
953
- VALUE rb_ca_repeat_new (VALUE cary, int8_t ndim, ca_size_t *count);
954
1345
  VALUE rb_ca_repeat (int argc, VALUE *argv, VALUE self);
955
1346
 
956
- /* --- ca_obj_unbound_repeat.c --- */
957
-
958
- VALUE rb_ca_ubrep_shave (VALUE self, VALUE other);
959
- VALUE rb_ca_ubrep_new (VALUE cary, int32_t rep_ndim, ca_size_t *rep_dim);
960
- VALUE ca_ubrep_bind_with (VALUE self, VALUE other);
961
-
962
- /* --- ca_obj_reduce.c --- */
963
-
964
- CAReduce *ca_reduce_new (CArray *carray, ca_size_t count, ca_size_t offset);
1347
+ /* --- carray_broadcast.c --- */
965
1348
 
966
- /* --- ca_iter_dimension --- */
1349
+ VALUE ca_broadcast_view (VALUE src, int8_t ndim, ca_size_t *target_dim);
1350
+ void ca_broadcast_pair (volatile VALUE *self, volatile VALUE *other);
967
1351
 
968
- VALUE rb_dim_iter_new (VALUE vca, CAIndexInfo *info);
1352
+ /* --- ca_iter_dimension retired: CADimensionIterator -> CASlabIterator --- */
969
1353
 
970
1354
  /* -------------------------------------------------------------------- */
971
1355
 
972
1356
  /* API : defining new array */
973
1357
 
974
- void * malloc_with_check(size_t size);
1358
+ /* Register an obj_type. func_size is sizeof(*func) as the *caller* sees it:
1359
+ the table is copied by that length and the remainder zero-filled, so a
1360
+ caller built against an older header leaves later slots NULL and reaches
1361
+ the default handling for them instead of feeding the dispatcher whatever
1362
+ followed its shorter struct. Pass sizeof of the table being installed:
1363
+
1364
+ ca_install_obj_type(klass, &td, mask_klass, &mask_td,
1365
+ &my_func, sizeof(my_func));
1366
+
1367
+ A func_size larger than this build's struct means the caller was compiled
1368
+ against a newer carray; that is reported rather than truncated. */
975
1369
 
976
1370
  int
977
- ca_install_obj_type (VALUE klass,
978
- const rb_data_type_t *typeddata,
979
- VALUE mask_klass,
980
- const rb_data_type_t *mask_typeddata,
981
- ca_operation_function_t func);
1371
+ ca_install_obj_type (VALUE klass,
1372
+ const rb_data_type_t *typeddata,
1373
+ VALUE mask_klass,
1374
+ const rb_data_type_t *mask_typeddata,
1375
+ const ca_operation_function_t *func,
1376
+ size_t func_size);
982
1377
 
983
1378
 
984
1379
  VALUE ca_data_type_class (int8_t data_type);
@@ -992,22 +1387,72 @@ void ca_free_nop (void *ap);
992
1387
  /* API : query of array properties */
993
1388
 
994
1389
  int ca_is_scalar (void *ap);
1390
+
1391
+ /* ca_is_entity indexes ca_func[], so expanding it inline compiles in the
1392
+ current sizeof(ca_operation_function_t) as the array stride. Sources built
1393
+ with the rest of carray are recompiled whenever a slot is added and get the
1394
+ macro; anything built separately gets the function, so that a later slot
1395
+ addition cannot silently re-index the table underneath it. (Reading
1396
+ ca_func[] directly carries the same coupling, and is left available to
1397
+ callers that ask for it deliberately.) */
1398
+ #ifdef CARRAY_BUILD
995
1399
  #define ca_is_entity(ca) ( ca_func[(ca)->obj_type].entity_type == CA_REAL_ARRAY )
996
- int ca_is_virtual (void *ap);
1400
+ #else
1401
+ int ca_is_entity (const void *ap);
1402
+ #endif
1403
+
1404
+ int ca_is_view (void *ap);
1405
+
1406
+ /* True iff ca is a member of the CAStride family -- the views whose
1407
+ addressing is a linear stride expression over a single parent, and
1408
+ which ca_stride_compose_to_root therefore folds into
1409
+ root->ptr + base + sum(idx[k] * strides[k]). Currently CAStride,
1410
+ CARefer, CABlock, CARepeat, CATranspose, CAFarray and CAField, plus
1411
+ the mask array of each. Membership is decided by the operation table
1412
+ an obj_type was installed with, so an externally installed view that
1413
+ shares the table is recognised too. Passing a non-member to
1414
+ ca_stride_compose_to_root reads the struct past its end, so guard the
1415
+ call with this. (Defined in ca_obj_stride.c, out of line: it indexes
1416
+ ca_func[], and a function keeps that stride out of separately built
1417
+ callers.) */
1418
+ int ca_is_stride_family (const void *ap);
1419
+
997
1420
  int ca_is_readonly (void *ap);
998
1421
  int ca_is_value_array (void *ap);
999
1422
  int ca_is_mask_array (void *ap);
1423
+ #define ca_is_face(ca) ( ca_test_flag((ca), CA_FLAG_IS_FACE) )
1424
+ #define ca_is_lazy_marker(ca) ( ca_test_flag((ca), CA_FLAG_IS_LAZY_MARKER) )
1000
1425
 
1001
1426
  #define ca_is_attached(ca) ( (ca)->ptr != NULL )
1002
1427
  #define ca_is_empty(ca) ( (ca)->elements == 0 )
1003
1428
 
1429
+ /* Shorthand for TypedData_Get_Struct against the base CArray tag.
1430
+ Accepts any concrete subclass (CScalar / CAWrap / CAView subtypes)
1431
+ because their TypedData is registered with carray_data_type as parent. */
1432
+ #define GetCArray(obj, ca) \
1433
+ TypedData_Get_Struct((obj), CArray, &carray_data_type, (ca))
1434
+
1435
+ /* True iff ca_attach(ca) is essentially O(1) — entity arrays (already
1436
+ attached), CAWrap, CScalar, and CAStride-family views whose composed
1437
+ strides are row-major contiguous (alias-attach path). Used by
1438
+ kernel_iterator's L1 alias decision (ca_iter_can_alias level 1) and
1439
+ by overlay-view dispatch. The name says the structural property
1440
+ (= aliasable without materialise), not the perf characteristic. */
1441
+ int ca_attach_is_alias (void *ap);
1442
+
1443
+ /* OR operand masks into
1444
+ ca_out->mask without ca_attach on operand masks (= gathers via
1445
+ ca_xfer_all into arena scratch then byte OR-folds). ca_out must be
1446
+ a freshly templated entity. For bang variant where ca_out IS one of
1447
+ the operands, the existing mask is preserved as initial accumulator. */
1448
+ void ca_mask_overlay_safe (CArray *ca_out, int n, ...);
1449
+
1004
1450
  #define ca_is_caobject(ca) ( (ca)->obj_type == CA_OBJ_OBJECT )
1005
1451
 
1006
1452
  int ca_is_fixlen_type (void *ap);
1007
1453
  int ca_is_boolean_type (void *ap);
1008
1454
  int ca_is_numeric_type (void *ap);
1009
1455
  int ca_is_integer_type (void *ap);
1010
- int ca_is_unsigned_type (void *ap);
1011
1456
  int ca_is_float_type (void *ap);
1012
1457
  int ca_is_complex_type (void *ap);
1013
1458
  int ca_is_object_type (void *ap);
@@ -1052,8 +1497,8 @@ CArray *ca_template_safe (void *ap); /* use rb_ca_template() */
1052
1497
  CArray *ca_template_safe2 (void *ap, int8_t data_type, ca_size_t bytes);
1053
1498
  /* use rb_ca_template() */
1054
1499
 
1055
- void ca_paste (void *ap, ca_size_t *idx, void *sp);
1056
- void ca_cut (void *ap, ca_size_t *offset, void *sp);
1500
+ /* ca_paste / ca_clip / ca_cut (sub-region copy in/out) removed in 3.0; see
1501
+ lib/extras/crop_paste.rb for the Ruby thin wrapper replacements. */
1057
1502
  void ca_fill (void *ap, void *ptr);
1058
1503
 
1059
1504
  /* API : fetch, store */
@@ -1061,22 +1506,96 @@ void ca_fill (void *ap, void *ptr);
1061
1506
  void ca_addr2index (void *ap, ca_size_t addr, ca_size_t *idx);
1062
1507
  ca_size_t ca_index2addr (void *ap, ca_size_t *idx);
1063
1508
 
1064
- void *ca_ptr_at_index (void *ap, ca_size_t *idx);
1065
- void *ca_ptr_at_addr (void *ap, ca_size_t addr);
1066
1509
 
1067
1510
  void ca_fetch_index (void *ap, ca_size_t *idx, void *ptr);
1068
1511
  void ca_fetch_addr (void *ap, ca_size_t addr, void *ptr);
1069
1512
  void ca_store_index (void *ap, ca_size_t *idx, void *ptr);
1070
1513
  void ca_store_addr (void *ap, ca_size_t addr, void *ptr);
1514
+ void ca_xfer_index (void *ap, ca_size_t *idx, void *data, int dir);
1515
+ void ca_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data, int dir);
1516
+ /* Shared predicate: detect if addrs[] is a sequential run
1517
+ (addrs[i] == addrs[0]+i for all i). Used by ca_xfer_addrs_dispatch and
1518
+ by view xfer_addrs slots for whole-view / sub-region run detection ->
1519
+ opportunistic engine dispatch. */
1520
+ int ca_xfer_addrs_is_sequential_run (ca_size_t n, ca_size_t *addrs,
1521
+ ca_size_t *base_out);
1522
+ /* Y.1.e: resolve cand through identity CAStride compose-fold to find an
1523
+ attached root. Returns cand if cand->ptr is set, cand is not CAStride
1524
+ family, or no identity compose-fold path exists; otherwise returns the
1525
+ resolved root (which has ptr). Used by view xfer_addrs slots to lift
1526
+ parent->ptr gate through view CAStride layers (= chain pattern). */
1527
+ CArray *ca_resolve_attached_root_via_identity (CArray *cand);
1528
+
1529
+ /* Shared gate for the xfer_stride slots' structural fast paths.
1530
+
1531
+ An xfer_stride request is given over the view's linear ADDRESSES (see the
1532
+ slot comment above), so request axis k need not be view axis k: a caller
1533
+ is free to hand over a transposed region -- counts/strides in one order,
1534
+ the packed destination buffer in another -- and a degenerate axis makes
1535
+ that indistinguishable from an axis-aligned request by divisibility alone
1536
+ (an (n, 1) view has the same native step on both axes). A structural path
1537
+ that composes request axis k onto view axis k must therefore ask first:
1538
+ does request axis k advance view axis k, and stay inside it for the whole
1539
+ traversal? Returns 1 when that holds for every axis (count <= 1 axes move
1540
+ nothing and always pass), 0 when the request is not such a box -- the
1541
+ caller then takes its per-cell fallback, which is address-correct for any
1542
+ request. ndim is the request's rank, which the slots' wiring keeps equal
1543
+ to ca->ndim. */
1544
+ int ca_xfer_stride_request_is_axis_box (void *ap, ca_size_t *starts,
1545
+ ca_size_t *counts,
1546
+ ca_size_t *strides);
1547
+
1548
+ void ca_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
1549
+ ca_size_t *strides, void *data, int dir);
1550
+ void ca_xfer_all (void *ap, void *data, int dir);
1071
1551
 
1072
1552
  void ca_copy_data (void *ap, char *ptr);
1073
1553
  void ca_sync_data (void *ap, char *ptr);
1074
1554
  void ca_fill_data (void *ap, void *ptr);
1075
1555
 
1556
+ /* Write one value into part of a view. ptr is one element's worth of bytes.
1557
+ Both describe the region over the view's own linear addresses; see the
1558
+ fill_stride slot comment for why addresses rather than an index box.
1559
+ A view without the matching slot gets a per-cell default that descends
1560
+ through xfer_index, so the region is still all that gets touched. */
1561
+ void ca_fill_stride (void *ap, ca_size_t base, int8_t ndim,
1562
+ ca_size_t *counts, ca_size_t *steps, void *ptr);
1563
+ void ca_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr);
1564
+
1565
+ /* For slot implementations: the per-cell walk, to stand in for regions this
1566
+ view cannot pass on, and the test for the one region it always can. */
1567
+ void ca_fill_stride_default (void *ap, ca_size_t base, int8_t ndim,
1568
+ ca_size_t *counts, ca_size_t *steps, void *ptr);
1569
+ void ca_fill_addrs_default (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr);
1570
+
1571
+ /* For a view whose fill is a read-modify-write of its parent and so has no
1572
+ region to pass down: walk the region and feed its addresses to the batched
1573
+ address slot in windows, rather than descending the chain per cell. */
1574
+ void ca_fill_stride_via_addrs (void *ap, ca_size_t base, int8_t ndim,
1575
+ ca_size_t *counts, ca_size_t *steps,
1576
+ void *ptr);
1577
+
1578
+ /* The entity fill, against a buffer the caller resolved for itself. A source
1579
+ that hands out its pointer on demand rather than keeping one at rest gets
1580
+ the same run-writing walk without having to write it again, and without
1581
+ publishing the pointer into ca->ptr to do so. */
1582
+ void ca_fill_stride_buffer (char *dst, ca_size_t bytes, ca_size_t base,
1583
+ int8_t ndim, ca_size_t *counts,
1584
+ ca_size_t *steps, void *ptr);
1585
+ void ca_fill_addrs_buffer (char *dst, ca_size_t bytes, ca_size_t n,
1586
+ ca_size_t *addrs, void *ptr);
1587
+ int ca_fill_stride_is_whole (void *ap, ca_size_t base, int8_t ndim,
1588
+ ca_size_t *counts, ca_size_t *steps);
1589
+
1590
+ /* Fill the whole of `ca` by handing its own extent to ca_fill_stride: the
1591
+ region every caller means when it says "all of me". Views use it to route
1592
+ a full-coverage fill_data into the region path. */
1593
+ void ca_fill_stride_whole (void *ap, void *ptr);
1594
+
1076
1595
  /* API : mask handling */
1077
1596
 
1078
1597
  extern VALUE CA_UNDEF;
1079
- extern VALUE CA_NIL;
1598
+ extern VALUE CA_UNSPECIFIED;
1080
1599
 
1081
1600
  boolean8_t *ca_mask_ptr (void *ap);
1082
1601
  int ca_has_mask (void *ap);
@@ -1110,9 +1629,6 @@ void ca_val2val (int8_t data_type1, void *ptr1, int8_t data_type2, void *ptr2
1110
1629
  VALUE ca_ptr2obj (void *ap, void *ptr); /* use rb_ca_ptr2obj() */
1111
1630
  void ca_obj2ptr (void *ap, VALUE obj, void *ptr); /* use rb_ca_ptr2obj() */
1112
1631
 
1113
- void ca_block_from_carray(CArray *cs,
1114
- ca_size_t *start, ca_size_t *step, ca_size_t *count, CArray *ca);
1115
-
1116
1632
  #define ca_wrap_writable(obj, data_type) \
1117
1633
  (obj = rb_ca_wrap_writable(obj, INT2NUM(data_type)), (CArray*) DATA_PTR(obj))
1118
1634
  #define ca_wrap_readonly(obj, data_type) \
@@ -1122,8 +1638,6 @@ VALUE rb_carray_wrap_ptr (int8_t data_type,
1122
1638
  int8_t ndim, ca_size_t *dim, ca_size_t bytes,
1123
1639
  CArray *mask, char *ptr, VALUE refer);
1124
1640
 
1125
- void * ca_to_cptr (void *ap);
1126
-
1127
1641
  /* API : utils */
1128
1642
 
1129
1643
  boolean8_t *ca_allocate_mask_iterator (int n, ...);
@@ -1140,14 +1654,19 @@ void ca_parse_range_without_check (VALUE arg, ca_size_t size,
1140
1654
 
1141
1655
  int ca_equal (void *ap, void *bp);
1142
1656
  void ca_zerodiv(void) __attribute__((noreturn));
1143
- int32_t ca_rand (double rmax);
1657
+ /* ca_rand removed in 3.0; use rb_random_real/rb_random_ulong_limited instead */
1144
1658
  ca_size_t ca_bounds_normalize_index (int8_t bounds, ca_size_t size0, ca_size_t k);
1659
+ int rb_ca_normalize_axis_value (VALUE self, VALUE raxis, const char *name);
1660
+ int rb_ca_normalize_axis_for_ndim (long raw, int ndim, const char *name);
1661
+ int8_t rb_ca_parse_reduce_axes_kw_ctx (VALUE axis_val, CArray *ca,
1662
+ int8_t *out_axes, const char *ctx);
1145
1663
 
1146
1664
  /* API : high level */
1147
1665
 
1148
1666
  /* parsing options */
1149
1667
  VALUE rb_pop_options (int *argc, VALUE **argv);
1150
1668
  void rb_scan_options (VALUE opt, const char *spec_in, ...);
1669
+ void rb_reject_options (VALUE opt);
1151
1670
  void rb_set_options (VALUE opt, const char *spec_in, ...);
1152
1671
 
1153
1672
  /* predicates for check object is carray or cscalar */
@@ -1157,6 +1676,7 @@ void rb_check_carray_object (VALUE arg);
1157
1676
 
1158
1677
  /* specific Data_Wrap_Struct for carray */
1159
1678
  VALUE ca_wrap_struct (void *ap);
1679
+ VALUE ca_wrap_struct_as (void *ap, VALUE klass);
1160
1680
 
1161
1681
  /* query data_type */
1162
1682
  int8_t rb_ca_guess_type (VALUE obj);
@@ -1172,7 +1692,6 @@ void rb_ca_scan_index (int ca_ndim, ca_size_t *ca_dim, ca_size_t elements,
1172
1692
  /* cast */
1173
1693
  int rb_ca_test_castable (VALUE other);
1174
1694
  VALUE rb_ca_binop_pass_to_other (VALUE self, VALUE other, ID method);
1175
- void rb_ca_cast_self (volatile VALUE *self);
1176
1695
  void rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other);
1177
1696
  void rb_ca_cast_other (VALUE *self, volatile VALUE *other);
1178
1697
 
@@ -1180,20 +1699,24 @@ VALUE rb_ca_wrap_writable (VALUE obj, VALUE vtype);
1180
1699
  VALUE rb_ca_wrap_readonly (VALUE obj, VALUE vtype);
1181
1700
 
1182
1701
  /* inheritance */
1183
- VALUE rb_ca_data_type_inherit (VALUE self, VALUE other);
1184
- VALUE rb_ca_data_type_import (VALUE self, VALUE data_type);
1702
+ /* rb_ca_data_type_inherit / rb_ca_data_type_import were removed in 3.0.
1703
+ data_class lives on
1704
+ Face (CARecord) tail; view ctors no longer carry data_class via
1705
+ @data_class ivar — Face dispatch (CA_FACE_LIFT_IF_FACE) handles it. */
1185
1706
  VALUE rb_ca_set_parent (VALUE self, VALUE obj);
1186
- /* call once for a virtual carray */
1707
+ /* call once for a view carray */
1187
1708
 
1188
1709
  /* freeze and decraration of modifing contents of carray */
1189
1710
  VALUE rb_ca_freeze (VALUE self);
1190
- void rb_ca_modify (VALUE self);
1711
+ VALUE rb_ca_set_read_only_flag (VALUE self);
1712
+ void rb_ca_modify (VALUE self); /* guard: rb_check_frozen(self) + ca_is_readonly */
1191
1713
 
1192
1714
  /* attributes */
1193
1715
  VALUE rb_ca_obj_type (VALUE self);
1194
1716
  VALUE rb_ca_data_type (VALUE self);
1195
1717
  VALUE rb_ca_ndim (VALUE self);
1196
1718
  VALUE rb_ca_bytes (VALUE self);
1719
+ VALUE rb_ca_flags (VALUE self);
1197
1720
  VALUE rb_ca_elements (VALUE self);
1198
1721
  VALUE rb_ca_dim (VALUE self);
1199
1722
  VALUE rb_ca_dim0 (VALUE self);
@@ -1206,7 +1729,6 @@ VALUE rb_ca_parent (VALUE self);
1206
1729
  VALUE rb_ca_is_fixlen_type (VALUE self);
1207
1730
  VALUE rb_ca_is_boolean_type (VALUE self);
1208
1731
  VALUE rb_ca_is_integer_type (VALUE self);
1209
- VALUE rb_ca_is_unsigned_type (VALUE self);
1210
1732
  VALUE rb_ca_is_float_type (VALUE self);
1211
1733
  VALUE rb_ca_is_complex_type (VALUE self);
1212
1734
  VALUE rb_ca_is_object_type (VALUE self);
@@ -1225,10 +1747,12 @@ VALUE rb_ca_is_scalar (VALUE self);
1225
1747
  VALUE rb_obj_is_data_class (VALUE rtype);
1226
1748
  VALUE rb_ca_has_data_class (VALUE self);
1227
1749
  VALUE rb_ca_data_class (VALUE self);
1750
+ /* rb_ca_set_data_class was removed in 3.0. The Ruby method
1751
+ CArray#data_class= raises ArgumentError with migration message. */
1228
1752
  VALUE rb_ca_data_class_decode (VALUE self, VALUE str);
1229
1753
  VALUE rb_ca_data_class_encode (VALUE self, VALUE obj);
1230
1754
  VALUE rb_ca_members (VALUE self);
1231
- VALUE rb_ca_field_as_member (VALUE self, VALUE sym);
1755
+ VALUE rb_ca_face_field (VALUE self, VALUE sym);
1232
1756
  VALUE rb_ca_fields_at (int argc, VALUE *argv, VALUE self);
1233
1757
  VALUE rb_ca_fields (VALUE self);
1234
1758
 
@@ -1242,8 +1766,6 @@ VALUE rb_ca_mask_array (VALUE self);
1242
1766
  VALUE rb_ca_set_mask (VALUE self, VALUE val);
1243
1767
  VALUE rb_ca_is_masked (VALUE self);
1244
1768
  VALUE rb_ca_is_not_masked (VALUE self);
1245
- VALUE rb_ca_count_masked (VALUE self);
1246
- VALUE rb_ca_count_not_masked (VALUE self);
1247
1769
  VALUE rb_ca_unmask (VALUE self);
1248
1770
  VALUE rb_ca_mask_fill (VALUE self, VALUE fval);
1249
1771
  VALUE rb_ca_unmask_copy (VALUE self);
@@ -1256,6 +1778,9 @@ VALUE rb_ca_inherit_mask (VALUE self, int n, ...);
1256
1778
  /* copy */
1257
1779
 
1258
1780
  VALUE rb_ca_copy (VALUE self);
1781
+ VALUE rb_ca_to_ca (int argc, VALUE *argv, VALUE self);
1782
+ int ca_to_ca_writable_arg (int argc, VALUE *argv);
1783
+ NORETURN(void ca_to_ca_refuse_writable (VALUE self));
1259
1784
  VALUE rb_ca_template (VALUE self);
1260
1785
  VALUE rb_ca_template_with_type (VALUE self, VALUE rtype, VALUE rbytes);
1261
1786
  VALUE rb_ca_template_n (int n, ...);
@@ -1293,7 +1818,6 @@ VALUE rb_ca_elem_test_masked (VALUE self, VALUE vidx1);
1293
1818
 
1294
1819
  /* data type conversion */
1295
1820
  VALUE rb_ca_ptr2ptr (VALUE ra1, void *ptr1, VALUE ra2, void *ptr2);
1296
- #define rb_ca_cast_ptr (VALUE ra1, void *ptr1, VALUE ra2, void *ptr2);
1297
1821
  VALUE rb_ca_cast_block (ca_size_t n, VALUE ra1, void *ptr1,
1298
1822
  VALUE ra2, void *ptr2);
1299
1823
 
@@ -1309,10 +1833,8 @@ VALUE rb_ca_to_int64 (VALUE self);
1309
1833
  VALUE rb_ca_to_uint64 (VALUE self);
1310
1834
  VALUE rb_ca_to_float32 (VALUE self);
1311
1835
  VALUE rb_ca_to_float64 (VALUE self);
1312
- VALUE rb_ca_to_float128 (VALUE self);
1313
1836
  VALUE rb_ca_to_cmplx64 (VALUE self);
1314
1837
  VALUE rb_ca_to_cmplx128 (VALUE self);
1315
- VALUE rb_ca_to_cmplx256 (VALUE self);
1316
1838
  VALUE rb_ca_to_VALUE (VALUE self);
1317
1839
  #define rb_ca_to_object(self) rb_ca_to_VALUE(self)
1318
1840
 
@@ -1330,176 +1852,23 @@ VALUE rb_ca_where (VALUE self);
1330
1852
  VALUE rb_ca_swap_bytes_bang (VALUE self);
1331
1853
  VALUE rb_ca_swap_bytes (VALUE self);
1332
1854
 
1333
- /* API : CAMath functions */
1334
- VALUE ca_call_cfunc_1 (void (*func)(void *p0),
1335
- const char *fsync,
1336
- VALUE rcx0);
1337
-
1338
- VALUE ca_call_cfunc_2 (void (*func)(void*,void*),
1339
- const char *fsync,
1340
- VALUE rcy,
1341
- VALUE rcx1);
1342
-
1343
- VALUE ca_call_cfunc_3 (void (*func)(void*,void*,void*),
1344
- const char *fsync,
1345
- VALUE rcy,
1346
- VALUE rcx1,
1347
- VALUE rcx2);
1348
-
1349
- VALUE ca_call_cfunc_4 (void (*func)(void*,void*,void*,void*),
1350
- const char *fsync,
1351
- VALUE rcy,
1352
- VALUE rcx1,
1353
- VALUE rcx2,
1354
- VALUE rcx3);
1355
-
1356
- VALUE ca_call_cfunc_5 (void (*func)(void*,void*,void*,void*,void*),
1357
- const char *fsync,
1358
- VALUE rcy,
1359
- VALUE rcx1,
1360
- VALUE rcx2,
1361
- VALUE rcx3,
1362
- VALUE rcx4);
1363
-
1364
- VALUE ca_call_cfunc_6 (void (*func)(void*,void*,void*,void*,void*,void*),
1365
- const char *fsync,
1366
- VALUE rcy,
1367
- VALUE rcx1,
1368
- VALUE rcx2,
1369
- VALUE rcx3,
1370
- VALUE rcx4,
1371
- VALUE rcx5);
1372
-
1373
- VALUE ca_call_cfunc_7 (void (*func)(void*,void*,void*,void*,void*,void*,void*),
1374
- const char *fsync,
1375
- VALUE rcy,
1376
- VALUE rcx1,
1377
- VALUE rcx2,
1378
- VALUE rcx3,
1379
- VALUE rcx4,
1380
- VALUE rcx5,
1381
- VALUE rcx6);
1382
-
1383
- VALUE ca_call_cfunc_1_1 (int8_t dty,
1384
- int8_t dtx,
1385
- void (*mathfunc)(void*,void*), VALUE rx);
1386
-
1387
- VALUE ca_call_cfunc_1_2 (int8_t dty,
1388
- int8_t dtx1,
1389
- int8_t dtx2,
1390
- void (*mathfunc)(void*,void*,void*),
1391
- volatile VALUE rx1, volatile VALUE rx2);
1392
-
1393
- VALUE ca_call_cfunc_1_3 (int8_t dty,
1394
- int8_t dtx1,
1395
- int8_t dtx2,
1396
- int8_t dtx3,
1397
- void (*mathfunc)(void*,void*,void*,void*),
1398
- volatile VALUE rx1,
1399
- volatile VALUE rx2,
1400
- volatile VALUE rx3);
1401
-
1402
- VALUE ca_call_cfunc_1_4 (int8_t dty,
1403
- int8_t dtx1,
1404
- int8_t dtx2,
1405
- int8_t dtx3,
1406
- int8_t dtx4,
1407
- void (*mathfunc)(void*,void*,void*,void*,void*),
1408
- volatile VALUE rx1,
1409
- volatile VALUE rx2,
1410
- volatile VALUE rx3,
1411
- volatile VALUE rx4);
1412
-
1413
- VALUE ca_call_cfunc_1_5 (int8_t dty,
1414
- int8_t dtx1,
1415
- int8_t dtx2,
1416
- int8_t dtx3,
1417
- int8_t dtx4,
1418
- int8_t dtx5,
1419
- void (*mathfunc)(void*,void*,void*,void*,void*,void*),
1420
- volatile VALUE rx1,
1421
- volatile VALUE rx2,
1422
- volatile VALUE rx3,
1423
- volatile VALUE rx4,
1424
- volatile VALUE rx5);
1425
-
1426
- VALUE ca_call_cfunc_1_6 (int8_t dty,
1427
- int8_t dtx1,
1428
- int8_t dtx2,
1429
- int8_t dtx3,
1430
- int8_t dtx4,
1431
- int8_t dtx5,
1432
- int8_t dtx6,
1433
- void (*mathfunc)(void*,void*,void*,void*,void*,void*,void*),
1434
- volatile VALUE rx1,
1435
- volatile VALUE rx2,
1436
- volatile VALUE rx3,
1437
- volatile VALUE rx4,
1438
- volatile VALUE rx5,
1439
- volatile VALUE rx6);
1440
-
1441
- VALUE ca_call_cfunc_2_1 (int8_t dty1,
1442
- int8_t dty2,
1443
- int8_t dtx1,
1444
- void (*mathfunc)(void*,void*,void*),
1445
- volatile VALUE rx1);
1446
-
1447
- VALUE ca_call_cfunc_2_2 (int8_t dty1,
1448
- int8_t dty2,
1449
- int8_t dtx1,
1450
- int8_t dtx2,
1451
- void (*mathfunc)(void*,void*,void*,void*),
1452
- volatile VALUE rx1,
1453
- volatile VALUE rx2);
1454
-
1455
- VALUE ca_call_cfunc_2_3 (int8_t dty1,
1456
- int8_t dty2,
1457
- int8_t dtx1,
1458
- int8_t dtx2,
1459
- int8_t dtx3,
1460
- void (*mathfunc)(void*,void*,void*,void*,void*),
1461
- volatile VALUE rx1,
1462
- volatile VALUE rx2,
1463
- volatile VALUE rx3);
1464
-
1465
- VALUE ca_call_cfunc_2_4 (int8_t dty1,
1466
- int8_t dty2,
1467
- int8_t dtx1,
1468
- int8_t dtx2,
1469
- int8_t dtx3,
1470
- int8_t dtx4,
1471
- void (*mathfunc)(void*,void*,void*,void*,void*,void*),
1472
- volatile VALUE rx1,
1473
- volatile VALUE rx2,
1474
- volatile VALUE rx3,
1475
- volatile VALUE rx4) ;
1476
-
1477
- VALUE ca_call_cfunc_3_1 (int8_t dty1,
1478
- int8_t dty2,
1479
- int8_t dty3,
1480
- int8_t dtx1,
1481
- void (*mathfunc)(void*,void*,void*,void*),
1482
- volatile VALUE rx1);
1483
-
1484
- VALUE ca_call_cfunc_3_2 (int8_t dty1,
1485
- int8_t dty2,
1486
- int8_t dty3,
1487
- int8_t dtx1,
1488
- int8_t dtx2,
1489
- void (*mathfunc)(void*,void*,void*,void*,void*),
1490
- volatile VALUE rx1,
1491
- volatile VALUE rx2);
1492
-
1493
- VALUE ca_call_cfunc_3_3 (int8_t dty1,
1494
- int8_t dty2,
1495
- int8_t dty3,
1496
- int8_t dtx1,
1497
- int8_t dtx2,
1498
- int8_t dtx3,
1499
- void (*mathfunc)(void*,void*,void*,void*,void*,void*),
1500
- volatile VALUE rx1,
1501
- volatile VALUE rx2,
1502
- volatile VALUE rx3);
1855
+ /* API : CAMath functions
1856
+ *
1857
+ * Declarations live in carray_call_cfunc.h, co-generated with
1858
+ * carray_call_cfunc.c by ext/mk_call_cfunc.rb to keep prototypes
1859
+ * and definitions in lockstep. */
1860
+ #include "carray_call_cfunc.h"
1861
+
1862
+ /* -------------------------------------------------------------------- */
1863
+
1864
+ /* carray_loop.c — unified multi-dimensional index walk shared by
1865
+ each_index / each_with_index / map_index! / map_with_index! and by
1866
+ the construction-block sugar in rb_ca_initialize. */
1867
+ #define CA_LOOP_WITH_VALUE 1
1868
+ #define CA_LOOP_STORE 2
1869
+
1870
+ VALUE rb_ca_index_walk (VALUE self, CArray *ca, int8_t level,
1871
+ ca_size_t *idx, VALUE ridx, int mode);
1503
1872
 
1504
1873
  /* -------------------------------------------------------------------- */
1505
1874
 
@@ -1507,4 +1876,25 @@ void ca_debug ();
1507
1876
 
1508
1877
  /* -------------------------------------------------------------------- */
1509
1878
 
1879
+ /* Portable textbook sort kernels.
1880
+ These are layer ③ true-internal (ca_sort_kernels.h self-describes as
1881
+ "ext-internal, signatures may change across 3.x"). They are NOT pulled
1882
+ into the carray.h umbrella and NOT installed: the internal consumers (carray_sort_kernel.c / carray_sort.c /
1883
+ carray_partition.c / carray_kernels.c) include ca_sort_kernels.h
1884
+ directly. */
1885
+
1886
+ /* -------------------------------------------------------------------- */
1887
+ /* Public umbrella */
1888
+ /* -------------------------------------------------------------------- */
1889
+
1890
+ /* Pull the ext-author / math-backend surface in under the carray.h
1891
+ umbrella so a downstream gem reaches it with a single
1892
+ `#include "carray.h"`. Placed at the bottom so these sub-headers see
1893
+ every type / enum / struct defined above (ca_size_t, CA_NTYPE, CArray,
1894
+ ...). All sub-headers are include-guarded, so the carray.h re-entry
1895
+ from inside them is a no-op. */
1896
+
1897
+ #include "carray_math_kernel.h" /* kernel typedefs + rb_ca_call_* + dispatch tables */
1898
+ #include "ca_kernel_iterator.h" /* CA_FOR_EACH_SLAB / CA_WITH_WHOLE_VIEW / CA_SLAB_*_T */
1899
+
1510
1900
  #endif