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/ca_obj_face.h ADDED
@@ -0,0 +1,247 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_obj_face.h
4
+
5
+ Face mechanism — shared op helper signatures + lift/strip entry points.
6
+
7
+ Phase 1 (= PROPOSAL_CAFACE_PHASE_1.md): skeleton.
8
+ Phase 2 (= PROPOSAL_CAFACE_PHASE_2.md F.2.1): replace shared op helpers
9
+ with thin-forward to parent.
10
+
11
+ This header provides signatures for (1) shared op helpers (= thin-forward
12
+ for storage ops, alias-based since Face is data-layout identical to
13
+ parent), (2) `rb_ca_face_template` (struct duplicate + parent swap),
14
+ (3) `ca_face_lift` (= wrap hook at the tail of user-facing access
15
+ methods), (4) `ca_strip_face` (= Face-stripping helper at kernel_iterator
16
+ entry).
17
+
18
+ A Face is a "mask of a semantic type" (= identity layered on a storage
19
+ type such as int64, with no value conversion), sibling to CAFake which
20
+ was a "mask of data_type conversion".
21
+
22
+ --------------------------------------------------------------------------- */
23
+
24
+ #ifndef CA_OBJ_FACE_H
25
+ #define CA_OBJ_FACE_H
26
+
27
+ #include "carray.h"
28
+
29
+ /* -- shared op helpers (= thin-forward to parent, alias-based) --
30
+ Face is data-layout identical to parent (= storage type / bytes /
31
+ strides / dim all match), so:
32
+ - attach: parent attach; ptr aliases parent->ptr (= no xmalloc needed)
33
+ - sync: parent sync (= alias path, no copy back needed; propagates
34
+ via parent)
35
+ - detach: release ptr alias, parent detach
36
+ - xfer_*: delegate to parent's xfer_* (= identical shape / index space)
37
+ - fill_data: delegate to parent's ca_fill (= identical storage bytes)
38
+
39
+ Subclasses may override as needed (= default policy, not an invariant;
40
+ does not preclude a future transform Face). */
41
+
42
+ void ca_face_attach (void *ap);
43
+ void ca_face_sync (void *ap);
44
+ void ca_face_detach (void *ap);
45
+ void ca_face_fill_data (void *ap, void *ptr);
46
+ void ca_face_xfer_index (void *ap, ca_size_t *idx,
47
+ void *data, int dir);
48
+ void ca_face_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
49
+ void *data, int dir);
50
+ void ca_face_xfer_stride(void *ap, ca_size_t *starts, ca_size_t *counts,
51
+ ca_size_t *strides, void *data, int dir);
52
+ void ca_face_xfer_all (void *ap, void *data, int dir);
53
+
54
+ /* -- lift / strip helpers -- */
55
+
56
+ /* Struct duplicate + parent + shape swap (= MEMO §4.3; consumed by Face
57
+ subclass lift / clone / dup machinery in Phase 2). */
58
+ VALUE rb_ca_face_template (VALUE original_face, CArray *new_parent,
59
+ ca_size_t *new_dim);
60
+
61
+ /* At the tail of user-facing access methods, `if parent is a Face, wrap
62
+ the result as a Face`. Deployed in Phase 1 for `ca[...]`
63
+ (= rb_ca_aref / rb_ca_store); planned for block / refer / reshape /
64
+ transpose / sort etc. in Phase 2. */
65
+ VALUE ca_face_lift (VALUE view, VALUE face_parent);
66
+
67
+ /* Follow the Face flag down to parent, e.g. at kernel_iterator entry.
68
+ No call sites in Phase 1; wired into SRC_* path init_l2 in Phase 2
69
+ (F.2.6). */
70
+ CArray *ca_strip_face (CArray *src);
71
+
72
+ /* VALUE-level counterpart: walks the Face parent ivar chain to the root
73
+ storage VALUE. Used at ordering / search dispatcher entry so both the
74
+ switch (src->data_type) and downstream rb_ca_template* calls see the
75
+ root storage, not the Face surface. */
76
+ VALUE rb_ca_strip_face_value (VALUE v);
77
+
78
+ /* Face gate for the element-wise comparison operators (< <= > >=, eq, ne).
79
+ When self is a Face over numeric storage, descends both operands to
80
+ storage (ORDERABLE required) and reconciles a Face RHS via to_comparable;
81
+ a fixlen-storage Face or a non-Face self is left untouched. Called from
82
+ rb_ca_call_bincmp. See ca_obj_face.c for the full contract. */
83
+ void ca_face_reconcile_comparison (volatile VALUE *pself,
84
+ volatile VALUE *pother);
85
+
86
+ /* CAFace abstract base class init (rev11 2026-06-10).
87
+ Called from ruby_carray.c's Init after rb_cCAView is defined, before
88
+ CATime / CATimedelta Init. */
89
+ void Init_ca_face (void);
90
+
91
+ /* -- R.5: composite Face data_class universal dispatch --
92
+ Extern for direct C access from `rb_ca_data_class` (carray_attribute.c)
93
+ into the CARecord tail. CA_OBJ_RECORD identifies the obj_type (assigned
94
+ at runtime by ca_install_obj_type). To add a future composite Face,
95
+ follow the same pattern: add an extern here and one line of case in the
96
+ switch in carray_attribute.c. */
97
+ extern int8_t CA_OBJ_RECORD;
98
+ VALUE rb_ca_record_get_data_class (CArray *ca);
99
+
100
+ /* -- Convenience macro for view-creating method deployment (F.2.13) --
101
+ Insert at the tail of each view-creating Ruby method (= rb_ca_transpose
102
+ / rb_ca_reshape / etc.) just before return. `ca` is self's CArray *,
103
+ `obj` is the view result, `self` is the calling VALUE. Achieves Face
104
+ transparency in a single C-level line, subclass-agnostic.
105
+
106
+ Macroises the pattern hand-written at the tail of `rb_ca_fetch_method`
107
+ in Phase 1; applied uniformly to view-creating methods from Phase 2
108
+ F.2.13 onward. */
109
+ #define CA_FACE_LIFT_IF_FACE(obj, self, ca) do { \
110
+ if ( ca_is_face(ca) && rb_obj_is_kind_of((obj), rb_cCArray) ) { \
111
+ (obj) = ca_face_lift((obj), (self)); \
112
+ } \
113
+ } while (0)
114
+
115
+ /* -- Scalar fetch decode hook (storage -> surface) --
116
+ On the scalar-return path (= tail of rb_ca_fetch_index /
117
+ rb_ca_fetch_addr), if a Face-derived subclass defines a
118
+ `storage_to_scalar(raw_value)` Ruby callback, invoke it. This is a
119
+ decode (copy the storage value out and construct a new value object),
120
+ not a wrap (a zero-copy lens over live memory). Its write-direction
121
+ counterpart is `scalar_to_storage` (below).
122
+
123
+ Use cases:
124
+ - `dt[i]` for CATime / CATimedelta → Scalar decode
125
+ - `ca[i,j,k]` for user-implemented CAObject Face → custom Scalar return
126
+ - Removes the need for Ruby overrides (= alias_method :[] etc.),
127
+ subclass-agnostic
128
+
129
+ Guards:
130
+ - ca_is_face(ca): no-op for non-Face
131
+ - !is_a?(CArray): CArray results go through the lift path
132
+ (= CA_FACE_LIFT_IF_FACE)
133
+ - !UNDEF: don't decode the masked-element sentinel
134
+ - respond_to?(:storage_to_scalar): activates once the subclass adopts
135
+ the convention */
136
+ /* Face-local C-level dispatch table for storage_to_scalar, separate
137
+ from the global ca_operation_function_t (no API change to existing
138
+ subsystems). A Face subclass that wants the per-cell scalar fetch hot
139
+ path to skip rb_funcall registers its C function via
140
+ ca_face_register_storage_to_scalar(obj_type, fn) at Init time.
141
+ Unregistered obj_types (= external gem Faces that only define the Ruby
142
+ method) fall through to the rb_funcall branch. The Ruby
143
+ `storage_to_scalar` method is still defined as a regular method so
144
+ user-facing Ruby code may call it directly. */
145
+ typedef VALUE (*ca_face_storage_to_scalar_fn)(VALUE self, VALUE raw);
146
+
147
+ extern ca_face_storage_to_scalar_fn ca_face_storage_to_scalar_table[];
148
+
149
+ void ca_face_register_storage_to_scalar (int obj_type,
150
+ ca_face_storage_to_scalar_fn fn);
151
+
152
+ /* -- Scalar store encode hook (surface -> storage), mirror of the decode --
153
+ The write-direction counterpart of storage_to_scalar. Given a surface
154
+ value object (a Scalar / Time / DateTime), a Face-owned function returns
155
+ a storage-domain value (for datetime/timedelta: an Integer in self's
156
+ unit) that the storage cast in rb_ca_obj2ptr can consume directly. A
157
+ Face that needs no conversion (surface == storage) simply does not
158
+ register. Faces may either register a C fast-path function here or
159
+ define the Ruby method `scalar_to_storage`; the C table is consulted
160
+ first, then the Ruby fallback. */
161
+ typedef VALUE (*ca_face_scalar_to_storage_fn)(VALUE self, VALUE surface);
162
+
163
+ extern ca_face_scalar_to_storage_fn ca_face_scalar_to_storage_table[];
164
+
165
+ void ca_face_register_scalar_to_storage (int obj_type,
166
+ ca_face_scalar_to_storage_fn fn);
167
+
168
+ /* Single source of truth for the surface -> storage-domain conversion.
169
+ Returns `obj` unchanged when `ca` is not a Face or when no hook is
170
+ registered / defined (so a bare Integer / String passes through to the
171
+ existing storage cast). Otherwise returns the storage-domain value the
172
+ Face produced. Called from rb_ca_obj2ptr (single-cell / fill / masked /
173
+ range stores) and from the Array-of-scalars bulk store branch. */
174
+ VALUE ca_face_scalar_to_storage (VALUE self, CArray *ca, VALUE obj);
175
+
176
+ /* -- F.S0: Face state homogeneity check (= prerequisite for multi-Face APIs
177
+ such as CAStack lift) --
178
+ Per-obj_type C hook returning 1 if `a` and `b` (= both Face instances of
179
+ the same obj_type) have compatible state (= same struct tail fields).
180
+ Caller of `ca_face_state_compatible` guarantees both args are Face and
181
+ have identical obj_type. */
182
+ typedef int (*ca_face_state_compatible_fn)(CArray *a, CArray *b);
183
+
184
+ extern ca_face_state_compatible_fn ca_face_state_compatible_table[];
185
+
186
+ void ca_face_register_state_compatible (int obj_type,
187
+ ca_face_state_compatible_fn fn);
188
+
189
+ /* Dispatch order:
190
+ 1. C hook registered for a->obj_type → call hook, return its result
191
+ 2. Else if the Ruby class of `va` defines `face_state_compatible?`
192
+ on a Face subclass (= overrides CArray's default) → invoke with
193
+ `vb`, return RTEST of result
194
+ 3. Else → 1 (= default compatible, class identity only)
195
+ Caller must pre-check a->obj_type == b->obj_type. `va` / `vb` are
196
+ the Ruby VALUEs of the same instances (used only for the Ruby fallback
197
+ path). */
198
+ int ca_face_state_compatible (VALUE va, CArray *a, VALUE vb, CArray *b);
199
+
200
+ /* -- F.S1: Face state portability (= class-level predicate) --
201
+ Whether a Face class's state can be "moved" from one parent to
202
+ another -- i.e., whether list[0]'s state can stand in for the result
203
+ when a multi-parent operation (CAStack lift, compose family Face
204
+ preservation, etc.) is performed.
205
+
206
+ - portable = 1: state is metadata-only (= CATime unit, CACircular
207
+ @range), can be carried to the lifted view via ca_face_lift.
208
+ - portable = 0: state holds per-parent storage tied to the specific
209
+ parent (= CAConstString buffer); cannot be exchanged across parents.
210
+ Multi-parent operations must reject.
211
+
212
+ Default for unregistered obj_types is 1 (= safe for the common case of
213
+ metadata-only Faces, including Ruby-implemented Faces that don't reach
214
+ a C Init). Faces whose state holds per-parent storage MUST explicitly
215
+ register 0 (= CAConstString). */
216
+ extern int8_t ca_face_state_portable_table[];
217
+
218
+ void ca_face_register_state_portable (int obj_type, int portable);
219
+
220
+ /* Dispatch:
221
+ 1. C table entry registered for obj_type → return that value
222
+ 2. Else if the Ruby class `klass` defines a singleton method
223
+ `face_state_portable?` (= subclass owns it) → invoke and RTEST
224
+ 3. Else → 1 (= default portable)
225
+ `klass` is the Ruby class of the Face instance (used for the Ruby
226
+ fallback path). Pass Qnil when the class is unknown / unavailable
227
+ (= falls through to default). */
228
+ int ca_face_state_portable (int obj_type, VALUE klass);
229
+
230
+ #define CA_FACE_STORAGE_TO_SCALAR_IF_FACE(obj, self, ca) do { \
231
+ if ( ca_is_face(ca) && (obj) != CA_UNDEF && (obj) != Qnil \
232
+ && ! rb_obj_is_kind_of((obj), rb_cCArray) ) { \
233
+ ca_face_storage_to_scalar_fn _decode_fn = ca_face_storage_to_scalar_table[(ca)->obj_type]; \
234
+ if ( _decode_fn != NULL ) { \
235
+ (obj) = _decode_fn((self), (obj)); \
236
+ } \
237
+ else { \
238
+ static ID _id_storage_to_scalar = 0; \
239
+ if ( _id_storage_to_scalar == 0 ) _id_storage_to_scalar = rb_intern("storage_to_scalar"); \
240
+ if ( rb_respond_to((self), _id_storage_to_scalar) ) { \
241
+ (obj) = rb_funcall((self), _id_storage_to_scalar, 1, (obj)); \
242
+ } \
243
+ } \
244
+ } \
245
+ } while (0)
246
+
247
+ #endif /* CA_OBJ_FACE_H */