carray 2.0.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -25
  3. data/CHANGELOG.md +338 -0
  4. data/{NEWS.md → CHANGELOG.v1.md} +3 -0
  5. data/LICENSE +1 -1
  6. data/README.md +120 -36
  7. data/carray.gemspec +32 -30
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1244 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +124 -0
  15. data/ext/ca_binop_dispatch.h +152 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +239 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4367 -0
  26. data/ext/ca_kernel_iterator.h +2596 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +839 -0
  33. data/ext/ca_obj_binop.c +948 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +967 -0
  39. data/ext/ca_obj_face.c +750 -0
  40. data/ext/ca_obj_face.h +279 -0
  41. data/ext/ca_obj_fake.c +239 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +308 -0
  45. data/ext/ca_obj_grid.c +866 -440
  46. data/ext/ca_obj_meld.c +1039 -0
  47. data/ext/ca_obj_moncmp.c +588 -0
  48. data/ext/ca_obj_monop.c +1123 -0
  49. data/ext/ca_obj_object.c +866 -296
  50. data/ext/ca_obj_record.c +470 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +593 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +624 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1306 -0
  58. data/ext/ca_obj_shift.c +231 -793
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2584 -0
  62. data/ext/ca_obj_string.c +270 -0
  63. data/ext/ca_obj_tile.c +622 -0
  64. data/ext/ca_obj_time.c +548 -0
  65. data/ext/ca_obj_timedelta.c +437 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +785 -0
  68. data/ext/ca_obj_window.c +1202 -565
  69. data/ext/ca_op_byte_swap.c +175 -0
  70. data/ext/ca_op_cmplx64.h +123 -0
  71. data/ext/ca_op_ipower.c +316 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +473 -0
  75. data/ext/ca_sweep_engine.h +166 -0
  76. data/ext/ca_transform_common.c +235 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +810 -420
  80. data/ext/carray_access.c +873 -731
  81. data/ext/carray_attribute.c +98 -329
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +376 -0
  84. data/ext/carray_build_flags.h +3 -0
  85. data/ext/carray_call_cfunc.c +2897 -874
  86. data/ext/carray_call_cfunc.h +313 -0
  87. data/ext/carray_cast.c +1264 -315
  88. data/ext/carray_cast_func.rb +81 -40
  89. data/ext/carray_class.c +53 -63
  90. data/ext/carray_config.h +28 -0
  91. data/ext/carray_conversion.c +350 -346
  92. data/ext/carray_copy.c +168 -270
  93. data/ext/carray_core.c +1396 -206
  94. data/ext/carray_count.c +312 -0
  95. data/ext/carray_data_type.c +43 -19
  96. data/ext/carray_element.c +585 -213
  97. data/ext/carray_factorize.c +2542 -0
  98. data/ext/carray_generate.c +230 -559
  99. data/ext/carray_histogram.c +490 -0
  100. data/ext/carray_hold.c +228 -0
  101. data/ext/carray_index_classifier.c +1021 -0
  102. data/ext/carray_index_classifier.h +27 -0
  103. data/ext/carray_internal.h +136 -0
  104. data/ext/carray_kernels_bincmp.c +4446 -0
  105. data/ext/carray_kernels_binop.c +11001 -0
  106. data/ext/carray_kernels_init.c +1131 -0
  107. data/ext/carray_kernels_map.c +3467 -0
  108. data/ext/carray_kernels_moncmp.c +2097 -0
  109. data/ext/carray_kernels_monop.c +18313 -0
  110. data/ext/carray_kernels_reduce_aggregate.c +25837 -0
  111. data/ext/carray_kernels_reduce_boolean.c +330 -0
  112. data/ext/carray_kernels_reduce_cumulative.c +14593 -0
  113. data/ext/carray_kernels_reduce_extreme.c +16948 -0
  114. data/ext/carray_kernels_reduce_variance.c +3910 -0
  115. data/ext/carray_kernels_scan.c +3693 -0
  116. data/ext/carray_kernels_search.c +32138 -0
  117. data/ext/carray_kernels_sort.c +10626 -0
  118. data/ext/carray_kernels_triop.c +1392 -0
  119. data/ext/carray_lazy.c +737 -0
  120. data/ext/carray_loop.c +88 -200
  121. data/ext/carray_mask.c +853 -158
  122. data/ext/carray_math_kernel.h +120 -0
  123. data/ext/carray_mathfunc.c +10 -241
  124. data/ext/carray_median_percentile.c +1257 -0
  125. data/ext/carray_memory_view.c +1650 -0
  126. data/ext/carray_operator.c +1525 -320
  127. data/ext/carray_order.c +664 -1394
  128. data/ext/carray_partition.c +416 -0
  129. data/ext/carray_random.c +518 -0
  130. data/ext/carray_scatter.c +357 -0
  131. data/ext/carray_slab.c +1219 -0
  132. data/ext/carray_slab.h +84 -0
  133. data/ext/carray_sort.c +829 -0
  134. data/ext/carray_sort_kernel.c +620 -0
  135. data/ext/carray_struct.c +695 -0
  136. data/ext/carray_test.c +343 -229
  137. data/ext/carray_undef.c +34 -17
  138. data/ext/carray_utils.c +175 -74
  139. data/ext/extconf.rb +234 -55
  140. data/ext/mk_call_cfunc.rb +671 -0
  141. data/ext/mkkernel.rb +9096 -0
  142. data/ext/ruby_carray.c +211 -108
  143. data/ext/version.h +4 -14
  144. data/ext/version.rb +5 -13
  145. data/lib/carray/arrow_tensor.rb +401 -0
  146. data/lib/carray/attribute.rb +166 -0
  147. data/lib/carray/autoload_carray.rb +239 -0
  148. data/lib/carray/autoload_method_extension.rb +45 -0
  149. data/lib/carray/axis_group.rb +711 -0
  150. data/lib/carray/basics.rb +481 -0
  151. data/lib/carray/bincount_nd.rb +358 -0
  152. data/lib/carray/block_iterator.rb +614 -0
  153. data/lib/carray/boolean_reduce.rb +109 -0
  154. data/lib/carray/categorical.rb +561 -0
  155. data/lib/carray/categorical_iterator.rb +1084 -0
  156. data/lib/carray/complex.rb +150 -0
  157. data/lib/carray/conditional.rb +216 -0
  158. data/lib/carray/const_string.rb +228 -0
  159. data/lib/carray/construct.rb +160 -328
  160. data/lib/carray/core_extensions.rb +297 -0
  161. data/lib/carray/data_type_extension.rb +250 -0
  162. data/lib/carray/fixlen_string.rb +95 -0
  163. data/lib/carray/frame/concat.rb +132 -0
  164. data/lib/carray/frame/convert.rb +95 -0
  165. data/lib/carray/frame/csv_parser.rb +211 -0
  166. data/lib/carray/frame/frame.rb +642 -0
  167. data/lib/carray/frame/group.rb +186 -0
  168. data/lib/carray/frame/io.rb +321 -0
  169. data/lib/carray/frame/join.rb +248 -0
  170. data/lib/carray/frame/records.rb +99 -0
  171. data/lib/carray/frame/sort.rb +113 -0
  172. data/lib/carray/frame/verbs.rb +316 -0
  173. data/lib/carray/frame.rb +16 -0
  174. data/lib/carray/fuse_source.rb +123 -0
  175. data/lib/carray/fusion.rb +218 -0
  176. data/lib/carray/histogram.rb +512 -0
  177. data/lib/carray/inspect.rb +37 -26
  178. data/lib/carray/iterator.rb +58 -349
  179. data/lib/carray/lazy.rb +941 -0
  180. data/lib/carray/mask_gap_fill.rb +200 -0
  181. data/lib/carray/math.rb +78 -342
  182. data/lib/carray/meld_reduce.rb +289 -0
  183. data/lib/carray/methods/align_addr.rb +116 -0
  184. data/lib/carray/methods/bin.rb +128 -0
  185. data/lib/carray/methods/bincount.rb +87 -0
  186. data/lib/carray/methods/bit_string.rb +92 -0
  187. data/lib/carray/methods/broadcast.rb +63 -0
  188. data/lib/carray/methods/choose.rb +39 -0
  189. data/lib/carray/methods/composition.rb +280 -0
  190. data/lib/carray/methods/gather_nd.rb +206 -0
  191. data/lib/carray/methods/index.rb +39 -0
  192. data/lib/carray/methods/insert_block.rb +99 -0
  193. data/lib/carray/methods/is_in.rb +141 -0
  194. data/lib/carray/methods/join.rb +90 -0
  195. data/lib/carray/methods/locate_addr.rb +52 -0
  196. data/lib/carray/methods/mask_duplicates.rb +41 -0
  197. data/lib/carray/methods/meshgrid.rb +90 -0
  198. data/lib/carray/methods/mode.rb +126 -0
  199. data/lib/carray/methods/nunique.rb +46 -0
  200. data/lib/carray/methods/resize.rb +56 -0
  201. data/lib/carray/methods/snap.rb +161 -0
  202. data/lib/carray/methods/string_format.rb +57 -0
  203. data/lib/carray/methods/unique.rb +47 -0
  204. data/lib/carray/methods/value_counts.rb +71 -0
  205. data/lib/carray/mkmf.rb +124 -101
  206. data/lib/carray/runtime.rb +89 -0
  207. data/lib/carray/serialize.rb +478 -167
  208. data/lib/carray/slab_iterator.rb +305 -0
  209. data/lib/carray/stack.rb +291 -0
  210. data/lib/carray/string.rb +56 -180
  211. data/lib/carray/string_operation_extension.rb +289 -0
  212. data/lib/carray/struct.rb +335 -323
  213. data/lib/carray/struct_builder.rb +697 -0
  214. data/lib/carray/table.rb +41 -2
  215. data/lib/carray/time.rb +2654 -38
  216. data/lib/carray/window_iterator.rb +927 -0
  217. data/lib/carray.rb +55 -57
  218. data/yard-stubs/ca_obj_array.rb +385 -0
  219. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  220. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  221. data/yard-stubs/ca_obj_block.rb +73 -0
  222. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  223. data/yard-stubs/ca_obj_fake.rb +31 -0
  224. data/yard-stubs/ca_obj_farray.rb +32 -0
  225. data/yard-stubs/ca_obj_field.rb +45 -0
  226. data/yard-stubs/ca_obj_grid.rb +35 -0
  227. data/yard-stubs/ca_obj_refer.rb +72 -0
  228. data/yard-stubs/ca_obj_roll.rb +45 -0
  229. data/yard-stubs/ca_obj_shift.rb +43 -0
  230. data/yard-stubs/ca_obj_stride.rb +181 -0
  231. data/yard-stubs/ca_obj_tile.rb +29 -0
  232. data/yard-stubs/ca_obj_transpose.rb +40 -0
  233. data/yard-stubs/ca_obj_window.rb +49 -0
  234. data/yard-stubs/carray_access.rb +131 -0
  235. data/yard-stubs/carray_attribute.rb +246 -0
  236. data/yard-stubs/carray_broadcast.rb +37 -0
  237. data/yard-stubs/carray_cast.rb +489 -0
  238. data/yard-stubs/carray_class.rb +65 -0
  239. data/yard-stubs/carray_conversion.rb +76 -0
  240. data/yard-stubs/carray_copy.rb +79 -0
  241. data/yard-stubs/carray_core.rb +114 -0
  242. data/yard-stubs/carray_count.rb +79 -0
  243. data/yard-stubs/carray_element.rb +108 -0
  244. data/yard-stubs/carray_generate.rb +66 -0
  245. data/yard-stubs/carray_lazy.rb +23 -0
  246. data/yard-stubs/carray_loop.rb +140 -0
  247. data/yard-stubs/carray_mask.rb +259 -0
  248. data/yard-stubs/carray_math.rb +132 -0
  249. data/yard-stubs/carray_mathfunc.rb +45 -0
  250. data/yard-stubs/carray_median_percentile.rb +89 -0
  251. data/yard-stubs/carray_memory_view.rb +163 -0
  252. data/yard-stubs/carray_order.rb +312 -0
  253. data/yard-stubs/carray_random.rb +89 -0
  254. data/yard-stubs/carray_scatter.rb +106 -0
  255. data/yard-stubs/carray_slab.rb +57 -0
  256. data/yard-stubs/carray_sort.rb +163 -0
  257. data/yard-stubs/carray_test.rb +85 -0
  258. data/yard-stubs/carray_undef.rb +64 -0
  259. data/yard-stubs/carray_utils.rb +97 -0
  260. data/yard-stubs/ruby_carray.rb +193 -0
  261. metadata +220 -138
  262. data/Rakefile +0 -51
  263. data/TODO.md +0 -18
  264. data/ext/ca_iter_block.c +0 -257
  265. data/ext/ca_iter_dimension.c +0 -299
  266. data/ext/ca_iter_window.c +0 -214
  267. data/ext/ca_obj_mapping.c +0 -644
  268. data/ext/ca_obj_unbound_repeat.c +0 -529
  269. data/ext/carray_iterator.c +0 -641
  270. data/ext/carray_math.rb +0 -850
  271. data/ext/carray_numeric.c +0 -259
  272. data/ext/carray_sort_addr.c +0 -254
  273. data/ext/carray_stat.c +0 -2100
  274. data/ext/carray_stat_proc.rb +0 -1999
  275. data/ext/mkmath.rb +0 -741
  276. data/ext/ruby_ccomplex.c +0 -509
  277. data/ext/ruby_float_func.c +0 -86
  278. data/lib/carray/array.rb +0 -8
  279. data/lib/carray/autoload/autoload_base.rb +0 -19
  280. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  281. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  282. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  283. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  284. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  285. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  286. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  287. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  288. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  289. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  290. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  291. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  292. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  293. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  294. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  295. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  296. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  297. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  298. data/lib/carray/autoload.rb +0 -141
  299. data/lib/carray/basic.rb +0 -191
  300. data/lib/carray/broadcast.rb +0 -101
  301. data/lib/carray/compose.rb +0 -315
  302. data/lib/carray/convert.rb +0 -115
  303. data/lib/carray/info.rb +0 -110
  304. data/lib/carray/io/imagemagick.rb +0 -235
  305. data/lib/carray/mask.rb +0 -102
  306. data/lib/carray/math/histogram.rb +0 -177
  307. data/lib/carray/math/recurrence.rb +0 -93
  308. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  309. data/lib/carray/object/ca_obj_link.rb +0 -50
  310. data/lib/carray/object/ca_obj_pack.rb +0 -99
  311. data/lib/carray/obsolete.rb +0 -256
  312. data/lib/carray/ordering.rb +0 -181
  313. data/lib/carray/testing.rb +0 -51
  314. data/lib/carray/transform.rb +0 -109
  315. data/mailmap +0 -1
  316. data/misc/Methods.ja.md +0 -182
  317. data/misc/NOTE +0 -51
  318. data/spec/Classes/CABitfield_spec.rb +0 -58
  319. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  320. data/spec/Classes/CABlock_spec.rb +0 -205
  321. data/spec/Classes/CAField_spec.rb +0 -39
  322. data/spec/Classes/CAGrid_spec.rb +0 -75
  323. data/spec/Classes/CAMap_spec.rb +0 -0
  324. data/spec/Classes/CAMapping_spec.rb +0 -105
  325. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  326. data/spec/Classes/CAObject_spec.rb +0 -33
  327. data/spec/Classes/CARefer_spec.rb +0 -93
  328. data/spec/Classes/CARepeat_spec.rb +0 -65
  329. data/spec/Classes/CASelect_spec.rb +0 -22
  330. data/spec/Classes/CAShift_spec.rb +0 -16
  331. data/spec/Classes/CAStruct_spec.rb +0 -71
  332. data/spec/Classes/CATranspose_spec.rb +0 -60
  333. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  334. data/spec/Classes/CAWindow_spec.rb +0 -54
  335. data/spec/Classes/CAWrap_spec.rb +0 -8
  336. data/spec/Classes/CArray_spec.rb +0 -184
  337. data/spec/Classes/CScalar_spec.rb +0 -55
  338. data/spec/Features/feature_130_spec.rb +0 -19
  339. data/spec/Features/feature_attributes_spec.rb +0 -280
  340. data/spec/Features/feature_boolean_spec.rb +0 -98
  341. data/spec/Features/feature_broadcast.rb +0 -116
  342. data/spec/Features/feature_cast_function.rb +0 -19
  343. data/spec/Features/feature_cast_spec.rb +0 -33
  344. data/spec/Features/feature_class_spec.rb +0 -84
  345. data/spec/Features/feature_complex_spec.rb +0 -42
  346. data/spec/Features/feature_composite_spec.rb +0 -124
  347. data/spec/Features/feature_convert_spec.rb +0 -46
  348. data/spec/Features/feature_copy_spec.rb +0 -123
  349. data/spec/Features/feature_creation_spec.rb +0 -84
  350. data/spec/Features/feature_element_spec.rb +0 -144
  351. data/spec/Features/feature_extream_spec.rb +0 -54
  352. data/spec/Features/feature_generate_spec.rb +0 -74
  353. data/spec/Features/feature_index_spec.rb +0 -69
  354. data/spec/Features/feature_mask_spec.rb +0 -580
  355. data/spec/Features/feature_math_spec.rb +0 -97
  356. data/spec/Features/feature_order_spec.rb +0 -146
  357. data/spec/Features/feature_ref_store_spec.rb +0 -209
  358. data/spec/Features/feature_serialization_spec.rb +0 -125
  359. data/spec/Features/feature_stat_spec.rb +0 -397
  360. data/spec/Features/feature_virtual_spec.rb +0 -48
  361. data/spec/Features/method_eq_spec.rb +0 -81
  362. data/spec/Features/method_is_nan_spec.rb +0 -12
  363. data/spec/Features/method_map_spec.rb +0 -54
  364. data/spec/Features/method_max_with.rb +0 -20
  365. data/spec/Features/method_min_with.rb +0 -19
  366. data/spec/Features/method_ne_spec.rb +0 -18
  367. data/spec/Features/method_project_spec.rb +0 -188
  368. data/spec/Features/method_ref_spec.rb +0 -27
  369. data/spec/Features/method_round_spec.rb +0 -11
  370. data/spec/Features/method_s_linspace_spec.rb +0 -48
  371. data/spec/Features/method_s_span_spec.rb +0 -14
  372. data/spec/Features/method_seq_spec.rb +0 -47
  373. data/spec/Features/method_sort_with.rb +0 -43
  374. data/spec/Features/method_sorted_with.rb +0 -29
  375. data/spec/Features/method_span_spec.rb +0 -42
  376. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  377. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  378. data/spec/spec_all.rb +0 -10
  379. data/utils/ca_ase.rb +0 -21
  380. data/utils/ca_methods.rb +0 -15
  381. data/utils/cast_checker.rb +0 -30
  382. data/utils/convert_test.rb +0 -73
  383. data/utils/extract_yard.rb +0 -22
  384. data/utils/guess_shape.rb +0 -76
  385. data/utils/monkey_patch_methods.rb +0 -62
  386. data/utils/remove_resource_fork.sh +0 -5
@@ -0,0 +1,470 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ CARecord — composite Face for CAStruct-backed arrays. Face wrap for
4
+ arrays whose element type is a CAStruct subclass; data_class is
5
+ attached only to CARecord (not to bare CArray).
6
+
7
+ Storage layout matches the CAStruct backing (CA_FIXLEN bytes blob,
8
+ unchanged). Storage ops thin-forward to the parent via `ca_face_*`;
9
+ the tail holds `VALUE data_class`, pinned by a custom dmark.
10
+
11
+ Also housed here: data_class identity predicates
12
+ (`rb_obj_is_data_class` / `ca_check_data_class` /
13
+ `CArray.data_class?`) since data_class is a CARecord concern.
14
+
15
+ Sibling pattern references (VALUE tail + custom dmark):
16
+ ca_obj_time.c numeric Face
17
+ ca_obj_byte_swap.c endian Face
18
+
19
+ ---------------------------------------------------------------------------- */
20
+
21
+ #include "carray.h"
22
+ #include "ca_obj_face.h"
23
+
24
+ typedef struct {
25
+ /* === CAView prefix === */
26
+ int16_t obj_type;
27
+ int8_t data_type; /* fixed to CA_FIXLEN */
28
+ int8_t ndim;
29
+ int32_t flags; /* CA_FLAG_IS_FACE set */
30
+ ca_size_t bytes; /* = data_class::DATA_SIZE */
31
+ ca_size_t elements;
32
+ ca_size_t *dim;
33
+ char *ptr;
34
+ CArray *mask;
35
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
36
+ CArray *parent;
37
+ uint32_t attach;
38
+ uint8_t nosync;
39
+ /* === Face tail === */
40
+ VALUE data_class; /* CAStruct subclass (marked by custom dmark) */
41
+ } CARecord;
42
+
43
+ static size_t
44
+ ca_record_dsize (const void *ap)
45
+ {
46
+ const CARecord *ca = (const CARecord *) ap;
47
+ return sizeof(CARecord) + ca->ndim * sizeof(ca_size_t);
48
+ }
49
+
50
+ /* Pool framework hooks: single ndim-sized tail (dim) in the _pool
51
+ buffer, uniform with the rest of the pool-migrated views. */
52
+ static size_t
53
+ ca_record_pool_bytes (int8_t ndim)
54
+ {
55
+ ca_size_t n = (ndim > 0) ? ndim : 1;
56
+ return (size_t) n * sizeof(ca_size_t);
57
+ }
58
+
59
+ static void
60
+ ca_record_pool_init (void *ap, int8_t ndim)
61
+ {
62
+ CARecord *ca = (CARecord *) ap;
63
+ ca->dim = (ca_size_t *) ca->_pool;
64
+ }
65
+
66
+ /* Custom dmark: ca_mark handles the standard prefix; the data_class
67
+ tail VALUE must be marked explicitly (CAFace itself carries none). */
68
+ static void
69
+ ca_record_mark (void *ap)
70
+ {
71
+ CARecord *ca = (CARecord *) ap;
72
+ ca_mark(ca);
73
+ rb_gc_mark(ca->data_class);
74
+ }
75
+
76
+ const rb_data_type_t carecord_data_type = {
77
+ .parent = &caface_data_type,
78
+ .wrap_struct_name = "CARecord",
79
+ .function = {
80
+ .dmark = ca_record_mark,
81
+ .dfree = ca_free,
82
+ .dsize = ca_record_dsize,
83
+ .dcompact = NULL
84
+ },
85
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
86
+ };
87
+
88
+ int8_t CA_OBJ_RECORD; /* non-static: read by rb_ca_data_class in carray_attribute.c */
89
+ VALUE rb_cCARecord; /* non-static: exported for cross-file use */
90
+
91
+ /* ------------------------------------------------------------------- */
92
+
93
+ int
94
+ ca_record_setup (CARecord *ca, CArray *parent, VALUE data_class)
95
+ {
96
+ if ( parent->data_type != CA_FIXLEN ) {
97
+ rb_raise(rb_eTypeError,
98
+ "CARecord requires a CA_FIXLEN parent (got data_type=%d)",
99
+ parent->data_type);
100
+ }
101
+
102
+ ca->obj_type = CA_OBJ_RECORD;
103
+ ca->data_type = CA_FIXLEN;
104
+ ca->flags = CA_FLAG_IS_FACE;
105
+ ca->ndim = parent->ndim;
106
+ ca->bytes = parent->bytes;
107
+ ca->elements = parent->elements;
108
+ ca->ptr = NULL;
109
+ ca->mask = NULL;
110
+ if ( ! ca->_pool ) {
111
+ ca->dim = ALLOC_N(ca_size_t, parent->ndim);
112
+ }
113
+ memcpy(ca->dim, parent->dim, sizeof(ca_size_t) * parent->ndim);
114
+
115
+ ca->parent = parent;
116
+ ca->attach = 0;
117
+ ca->nosync = 0;
118
+
119
+ ca->data_class = data_class;
120
+
121
+ if ( ca_has_mask(parent) ) {
122
+ ca_create_mask((CArray *) ca);
123
+ }
124
+
125
+ if ( ca_is_scalar(parent) ) {
126
+ ca_set_flag(ca, CA_FLAG_SCALAR);
127
+ }
128
+
129
+ if ( ca_test_flag(parent, CA_FLAG_READ_ONLY) ) {
130
+ ca_set_flag(ca, CA_FLAG_READ_ONLY);
131
+ }
132
+
133
+ return 0;
134
+ }
135
+
136
+ CARecord *
137
+ ca_record_new (CArray *parent, VALUE data_class)
138
+ {
139
+ CARecord *ca = (CARecord *) ca_array_alloc(CA_OBJ_RECORD, parent->ndim);
140
+ ca_record_setup(ca, parent, data_class);
141
+ return ca;
142
+ }
143
+
144
+ static void
145
+ free_ca_record (void *ap)
146
+ {
147
+ CARecord *ca = (CARecord *) ap;
148
+ if ( ca != NULL ) {
149
+ ca_free(ca->mask);
150
+ if ( ca->_pool ) {
151
+ ca_array_free(ca); /* dim lives in _pool */
152
+ }
153
+ else {
154
+ xfree(ca->dim);
155
+ xfree(ca);
156
+ }
157
+ }
158
+ }
159
+
160
+ /* ------------------------------------------------------------------- */
161
+
162
+ static void *
163
+ ca_record_func_clone (void *ap)
164
+ {
165
+ CARecord *ca = (CARecord *) ap;
166
+ return ca_record_new(ca->parent, ca->data_class);
167
+ }
168
+
169
+ static void
170
+ ca_record_func_allocate (void *ap)
171
+ {
172
+ CARecord *ca = (CARecord *) ap;
173
+ /* alias: parent attach + alias parent->ptr (Face has identical data layout) */
174
+ ca_attach(ca->parent);
175
+ ca->ptr = ca->parent->ptr;
176
+ }
177
+
178
+ static void
179
+ ca_record_func_create_mask (void *ap)
180
+ {
181
+ CARecord *ca = (CARecord *) ap;
182
+ ca_update_mask(ca->parent);
183
+ if ( ! ca->parent->mask ) {
184
+ ca_create_mask(ca->parent);
185
+ }
186
+ ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
187
+ CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
188
+ }
189
+
190
+ ca_operation_function_t ca_record_func = {
191
+ -1, /* CA_OBJ_RECORD — filled by ca_install_obj_type */
192
+ CA_VIEW_ARRAY,
193
+ free_ca_record,
194
+ ca_record_func_clone,
195
+ ca_record_func_allocate,
196
+ ca_face_attach,
197
+ ca_face_sync,
198
+ ca_face_detach,
199
+ ca_face_fill_data,
200
+ ca_record_func_create_mask,
201
+ ca_face_xfer_index,
202
+ ca_face_xfer_addrs,
203
+ NULL, /* fold_stride: identity Face is not foldable */
204
+ ca_face_xfer_stride,
205
+ ca_face_xfer_all,
206
+ .fill_addrs = ca_face_fill_addrs,
207
+ .fill_stride = ca_face_fill_stride,
208
+ };
209
+
210
+ /* ------------------------------------------------------------------- */
211
+
212
+ /* Internal C builder — shared by .new (self-allocated parent) and
213
+ .wrap (user-supplied parent) paths. Pins parent_val via
214
+ rb_ca_set_parent for GC + lifecycle protection, and preallocates
215
+ the `member` ivar Hash used by rb_ca_face_field as a field-view
216
+ memoisation cache. */
217
+ static VALUE
218
+ ca_record_build (VALUE klass, VALUE data_class, VALUE parent_val)
219
+ {
220
+ CArray *parent_ca;
221
+ CARecord *ca;
222
+ VALUE obj;
223
+
224
+ if ( ! RTEST(rb_obj_is_data_class(data_class)) ) {
225
+ rb_raise(rb_eTypeError, "data_class must be a CAStruct subclass");
226
+ }
227
+ TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent_ca);
228
+ if ( parent_ca->data_type != CA_FIXLEN ) {
229
+ rb_raise(rb_eTypeError,
230
+ "CARecord requires a CA_FIXLEN parent (got data_type=%d)",
231
+ parent_ca->data_type);
232
+ }
233
+ ca = ca_record_new(parent_ca, data_class);
234
+ obj = TypedData_Wrap_Struct(klass, &carecord_data_type, ca);
235
+ rb_ca_set_parent(obj, parent_val);
236
+ rb_ivar_set(obj, rb_intern("member"), rb_hash_new());
237
+ return obj;
238
+ }
239
+
240
+ /* CARecord.new(data_class, *shape) or Sub.new(*shape) — atomic path:
241
+ allocate a fresh CA_FIXLEN entity and wrap it. Base class takes
242
+ `data_class` explicitly; a subclass that pinned its type via the
243
+ `data_class GeoCoord` DSL accepts only shape args. */
244
+ static VALUE
245
+ rb_ca_record_s_new (int argc, VALUE *argv, VALUE klass)
246
+ {
247
+ VALUE data_class, klass_dc, parent_val;
248
+ ca_size_t bytes;
249
+ ca_size_t dim[CA_RANK_MAX];
250
+ int ndim, shape_offset, i;
251
+
252
+ klass_dc = rb_iv_get(klass, "@data_class");
253
+ if ( ! NIL_P(klass_dc) ) {
254
+ /* subclass with DSL fix: shape args only */
255
+ data_class = klass_dc;
256
+ shape_offset = 0;
257
+ if ( argc > 0 && RTEST(rb_obj_is_data_class(argv[0])) ) {
258
+ rb_raise(rb_eArgError,
259
+ "subclass has fixed data_class via DSL; don't pass it again");
260
+ }
261
+ }
262
+ else {
263
+ /* base direct: first arg = data_class */
264
+ if ( argc < 1 ) {
265
+ rb_raise(rb_eArgError, "data_class required as first argument");
266
+ }
267
+ data_class = argv[0];
268
+ shape_offset = 1;
269
+ }
270
+ ndim = argc - shape_offset;
271
+ if ( ndim < 0 || ndim > CA_RANK_MAX ) {
272
+ rb_raise(rb_eArgError, "invalid number of shape arguments (%d)", ndim);
273
+ }
274
+ for ( i = 0; i < ndim; i++ ) {
275
+ dim[i] = NUM2SIZE(argv[shape_offset + i]);
276
+ }
277
+
278
+ if ( ! RTEST(rb_obj_is_data_class(data_class)) ) {
279
+ rb_raise(rb_eTypeError, "data_class must be a CAStruct subclass");
280
+ }
281
+ bytes = NUM2SIZE(rb_const_get(data_class, rb_intern("DATA_SIZE")));
282
+
283
+ parent_val = rb_carray_new(CA_FIXLEN, ndim, dim, bytes, NULL);
284
+ return ca_record_build(klass, data_class, parent_val);
285
+ }
286
+
287
+ /* CARecord.wrap(entity, data_class) or Sub.wrap(entity) — zero-copy
288
+ Face wrap of an existing CA_FIXLEN entity. Sibling of
289
+ CATime.wrap. */
290
+ static VALUE
291
+ rb_ca_record_s_wrap (int argc, VALUE *argv, VALUE klass)
292
+ {
293
+ VALUE entity_val, data_class, klass_dc;
294
+
295
+ klass_dc = rb_iv_get(klass, "@data_class");
296
+ if ( ! NIL_P(klass_dc) ) {
297
+ rb_scan_args(argc, argv, "1", &entity_val);
298
+ data_class = klass_dc;
299
+ }
300
+ else {
301
+ rb_scan_args(argc, argv, "2", &entity_val, &data_class);
302
+ }
303
+ rb_check_carray_object(entity_val);
304
+ return ca_record_build(klass, data_class, entity_val);
305
+ }
306
+
307
+ /* Direct C accessor for the CARecord tail data_class. Called by
308
+ rb_ca_data_class in carray_attribute.c, dispatched on obj_type so
309
+ there is no Ruby roundtrip. */
310
+ VALUE
311
+ rb_ca_record_get_data_class (CArray *ca)
312
+ {
313
+ return ((CARecord *) ca)->data_class;
314
+ }
315
+
316
+ /* Subclass DSL: `data_class Foo` inside `class Sub < CARecord`.
317
+ Set once and then immutable (reassignment raises). A zero-arg call
318
+ acts as a getter. The class ivar is what `.new` / `.wrap` read via
319
+ `rb_iv_get(klass, "@data_class")` to omit the explicit arg. */
320
+ static VALUE
321
+ rb_ca_record_s_data_class_dsl (int argc, VALUE *argv, VALUE klass)
322
+ {
323
+ VALUE current, given;
324
+
325
+ current = rb_iv_get(klass, "@data_class");
326
+ if ( argc == 0 ) {
327
+ return NIL_P(current) ? Qnil : current;
328
+ }
329
+ rb_scan_args(argc, argv, "1", &given);
330
+ if ( ! NIL_P(current) ) {
331
+ rb_raise(rb_eRuntimeError,
332
+ "data_class already fixed to %"PRIsVALUE
333
+ "; CARecord subclass data_class is immutable once set",
334
+ current);
335
+ }
336
+ if ( ! RTEST(rb_obj_is_data_class(given)) ) {
337
+ rb_raise(rb_eTypeError, "data_class must be a CAStruct subclass");
338
+ }
339
+ rb_iv_set(klass, "@data_class", given);
340
+ return given;
341
+ }
342
+
343
+ static VALUE
344
+ rb_ca_record_s_allocate (VALUE klass)
345
+ {
346
+ CARecord *ca;
347
+ return TypedData_Make_Struct(klass, CARecord, &carecord_data_type, ca);
348
+ }
349
+
350
+ static VALUE
351
+ rb_ca_record_initialize_copy (VALUE self, VALUE other)
352
+ {
353
+ CARecord *ca, *cs;
354
+ TypedData_Get_Struct(self, CARecord, &carecord_data_type, ca);
355
+ TypedData_Get_Struct(other, CARecord, &carecord_data_type, cs);
356
+ if ( ca_func[CA_OBJ_RECORD].pool_init ) {
357
+ ca_array_pool_alloc(ca, CA_OBJ_RECORD, cs->parent->ndim);
358
+ }
359
+ ca_record_setup(ca, cs->parent, cs->data_class);
360
+ return self;
361
+ }
362
+
363
+ /* ---------------------------------------------------------------------------
364
+ data_class identity predicates. A Ruby class that can serve as the
365
+ element type of a CARecord (i.e. the inner struct definition such as
366
+ GeoCoord / Pixel, not the CARecord subclass CAGeoCoord) must provide
367
+ the constants + methods checked below. `CArray.struct {...}` /
368
+ `CArray.union {...}` generate them automatically.
369
+
370
+ rb_obj_is_data_class(klass) duck-type predicate, Qtrue/Qfalse
371
+ ca_check_data_class(klass) same, raises on failure
372
+ CArray.data_class?(klass) Ruby surface for the predicate
373
+
374
+ Signatures stay in carray.h for cross-file extern use.
375
+ ------------------------------------------------------------------------- */
376
+
377
+ VALUE
378
+ rb_obj_is_data_class (VALUE rtype)
379
+ {
380
+ VALUE has_data_size, has_member_names, has_member_table;
381
+ VALUE has_encode, has_decode;
382
+ if ( TYPE(rtype) == T_CLASS ) {
383
+ has_data_size =
384
+ rb_funcall(rtype, rb_intern("const_defined?"), 1, rb_str_new2("DATA_SIZE"));
385
+ has_member_names =
386
+ rb_funcall(rtype, rb_intern("const_defined?"), 1, rb_str_new2("MEMBERS"));
387
+ has_member_table =
388
+ rb_funcall(rtype, rb_intern("const_defined?"), 1, rb_str_new2("MEMBER_TABLE"));
389
+ has_encode =
390
+ rb_funcall(rtype, rb_intern("method_defined?"), 1, rb_str_new2("encode"));
391
+ has_decode = rb_respond_to(rtype, rb_intern("decode"));
392
+ return ( RTEST(has_data_size) &&
393
+ RTEST(has_member_table) && RTEST(has_member_names) &&
394
+ RTEST(has_encode) && RTEST(has_decode) ) ? Qtrue : Qfalse;
395
+ }
396
+ return Qfalse;
397
+ }
398
+
399
+ void
400
+ ca_check_data_class (VALUE rtype)
401
+ {
402
+ if ( ! rb_obj_is_data_class(rtype) ) {
403
+ VALUE inspect = rb_inspect(rtype);
404
+ rb_raise(rb_eRuntimeError,
405
+ "<%s> is not a data_class, which should has the features\n" \
406
+ " * constant data_class::DATA_SIZE -> integer\n" \
407
+ " * constant data_class::MEMBERS -> array of string\n" \
408
+ " * constant data_class::MEMBER_TABLE -> hash\n" \
409
+ " * method data_class.decode(str) -> data_class object\n" \
410
+ " * method data_class#encode() -> string", StringValuePtr(inspect));
411
+ }
412
+ }
413
+
414
+ static VALUE
415
+ rb_ca_s_is_data_class (VALUE self, VALUE rklass)
416
+ {
417
+ return rb_obj_is_data_class(rklass);
418
+ }
419
+
420
+ /* Face-state homogeneity callback for promote_list / CAStack. Two
421
+ CARecord instances are compatible iff their data_class is identical;
422
+ without this, multi-parent constructions would silently mix records
423
+ with different DATA_SIZE or field schema. */
424
+ static int
425
+ ca_record_state_compatible (CArray *a, CArray *b)
426
+ {
427
+ CARecord *ra = (CARecord *) a;
428
+ CARecord *rb = (CARecord *) b;
429
+ return (ra->data_class == rb->data_class) ? 1 : 0;
430
+ }
431
+
432
+ /* ------------------------------------------------------------------------- */
433
+
434
+ void
435
+ Init_ca_obj_record (void)
436
+ {
437
+ rb_cCARecord = rb_define_class("CARecord", rb_cCAFace);
438
+
439
+ ca_record_func.struct_size = sizeof(CARecord);
440
+ ca_record_func.pool_bytes = ca_record_pool_bytes;
441
+ ca_record_func.pool_init = ca_record_pool_init;
442
+
443
+ CA_OBJ_RECORD = ca_install_obj_type(rb_cCARecord,
444
+ &carecord_data_type,
445
+ rb_cCArrayMask,
446
+ &carray_mask_data_type,
447
+ &ca_record_func, sizeof(ca_record_func));
448
+ rb_define_const(rb_cObject, "CA_OBJ_RECORD", INT2NUM(CA_OBJ_RECORD));
449
+
450
+ /* Homogeneity gate for promote_list / CAStack. The Ruby class is
451
+ always CARecord, so the default class-equality check cannot tell
452
+ GeoCoord apart from Pixel; the callback compares data_class per
453
+ instance. */
454
+ ca_face_register_state_compatible(CA_OBJ_RECORD,
455
+ ca_record_state_compatible);
456
+
457
+ rb_define_alloc_func(rb_cCARecord, rb_ca_record_s_allocate);
458
+ rb_define_method(rb_cCARecord, "initialize_copy",
459
+ rb_ca_record_initialize_copy, 1);
460
+
461
+ rb_define_singleton_method(rb_cCARecord, "new", rb_ca_record_s_new, -1);
462
+ rb_define_singleton_method(rb_cCARecord, "wrap", rb_ca_record_s_wrap, -1);
463
+ rb_define_singleton_method(rb_cCARecord, "data_class",
464
+ rb_ca_record_s_data_class_dsl, -1);
465
+
466
+ /* #data_class is inherited from CArray via the universal Face
467
+ dispatch (rb_ca_data_class reads the tail through obj_type). */
468
+
469
+ rb_define_singleton_method(rb_cCArray, "data_class?", rb_ca_s_is_data_class, 1);
470
+ }