carray 2.0.0 → 3.0.0

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