carray 3.0.2 → 3.0.4

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 (247) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +568 -0
  3. data/README.md +6 -6
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +220 -0
  7. data/ext/ca_axis_group.c +201 -123
  8. data/ext/ca_binop_dispatch.c +46 -52
  9. data/ext/ca_binop_dispatch.h +1 -1
  10. data/ext/ca_categorical_iterator.c +249 -183
  11. data/ext/ca_compare.c +7 -12
  12. data/ext/ca_for_buffer.h +21 -68
  13. data/ext/ca_group_iter.c +38 -23
  14. data/ext/ca_kernel_iterator.c +1765 -2076
  15. data/ext/ca_kernel_iterator.h +584 -566
  16. data/ext/ca_monop_dispatch.c +86 -63
  17. data/ext/ca_monop_dispatch.h +5 -0
  18. data/ext/ca_obj_array.c +223 -56
  19. data/ext/ca_obj_bincmp.c +172 -138
  20. data/ext/ca_obj_binop.c +116 -230
  21. data/ext/ca_obj_bitarray.c +40 -26
  22. data/ext/ca_obj_bitfield.c +100 -68
  23. data/ext/ca_obj_block.c +19 -9
  24. data/ext/ca_obj_byte_swap.c +45 -46
  25. data/ext/ca_obj_const_string.c +269 -44
  26. data/ext/ca_obj_face.c +612 -89
  27. data/ext/ca_obj_face.h +111 -47
  28. data/ext/ca_obj_fake.c +36 -79
  29. data/ext/ca_obj_farray.c +7 -3
  30. data/ext/ca_obj_field.c +33 -8
  31. data/ext/ca_obj_fixlen_string.c +23 -24
  32. data/ext/ca_obj_grid.c +541 -210
  33. data/ext/ca_obj_meld.c +331 -111
  34. data/ext/ca_obj_moncmp.c +80 -65
  35. data/ext/ca_obj_monop.c +177 -149
  36. data/ext/ca_obj_object.c +664 -248
  37. data/ext/ca_obj_record.c +63 -23
  38. data/ext/ca_obj_reduce.c +18 -16
  39. data/ext/ca_obj_refer.c +140 -58
  40. data/ext/ca_obj_remap.c +85 -24
  41. data/ext/ca_obj_repeat.c +24 -9
  42. data/ext/ca_obj_roll.c +121 -16
  43. data/ext/ca_obj_select.c +61 -58
  44. data/ext/ca_obj_select_axis.c +73 -107
  45. data/ext/ca_obj_shift.c +32 -102
  46. data/ext/ca_obj_stack.c +372 -122
  47. data/ext/ca_obj_stride.c +348 -140
  48. data/ext/ca_obj_string.c +88 -22
  49. data/ext/ca_obj_tile.c +38 -21
  50. data/ext/ca_obj_time.c +45 -31
  51. data/ext/ca_obj_timedelta.c +43 -29
  52. data/ext/ca_obj_transpose.c +17 -6
  53. data/ext/ca_obj_triop.c +125 -141
  54. data/ext/ca_obj_window.c +330 -44
  55. data/ext/ca_op_ipower.c +24 -11
  56. data/ext/ca_op_powi.h +57 -30
  57. data/ext/ca_pow5_table.h +656 -0
  58. data/ext/ca_sort_kernels.h +70 -0
  59. data/ext/ca_sweep_engine.c +104 -81
  60. data/ext/ca_sweep_engine.h +7 -20
  61. data/ext/ca_triop_dispatch.c +4 -1
  62. data/ext/ca_triop_dispatch.h +5 -2
  63. data/ext/caframe_csv_reader.c +542 -0
  64. data/ext/carray.h +241 -92
  65. data/ext/carray_access.c +608 -276
  66. data/ext/carray_address_basis.c +494 -97
  67. data/ext/carray_attribute.c +129 -4
  68. data/ext/carray_bincount.c +39 -7
  69. data/ext/carray_broadcast.c +56 -19
  70. data/ext/carray_build_flags.h +1 -1
  71. data/ext/carray_call_cfunc.c +108 -28
  72. data/ext/carray_cast.c +1576 -223
  73. data/ext/carray_cast_func.rb +77 -24
  74. data/ext/carray_class.c +4 -3
  75. data/ext/carray_conversion.c +208 -75
  76. data/ext/carray_copy.c +82 -24
  77. data/ext/carray_core.c +646 -162
  78. data/ext/carray_count.c +171 -88
  79. data/ext/carray_element.c +94 -60
  80. data/ext/carray_factorize.c +670 -324
  81. data/ext/carray_generate.c +260 -83
  82. data/ext/carray_histogram.c +209 -106
  83. data/ext/carray_hold.c +14 -16
  84. data/ext/carray_index_classifier.c +422 -243
  85. data/ext/carray_internal.h +692 -3
  86. data/ext/carray_kernels_bincmp.c +7 -0
  87. data/ext/carray_kernels_binop.c +487 -120
  88. data/ext/carray_kernels_init.c +653 -50
  89. data/ext/carray_kernels_moncmp.c +15 -8
  90. data/ext/carray_kernels_monop.c +99 -43
  91. data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
  92. data/ext/carray_kernels_reduce_boolean.c +112 -36
  93. data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
  94. data/ext/carray_kernels_reduce_extreme.c +3032 -2892
  95. data/ext/carray_kernels_reduce_variance.c +439 -500
  96. data/ext/carray_kernels_scan.c +1097 -488
  97. data/ext/carray_kernels_search.c +3787 -2176
  98. data/ext/carray_kernels_sort.c +1200 -920
  99. data/ext/carray_kernels_triop.c +479 -7
  100. data/ext/carray_key_windows.c +216 -0
  101. data/ext/carray_lazy.c +967 -153
  102. data/ext/carray_loop.c +81 -65
  103. data/ext/carray_mask.c +910 -324
  104. data/ext/carray_math_kernel.h +1 -0
  105. data/ext/carray_median_percentile.c +299 -100
  106. data/ext/carray_memory_view.c +872 -758
  107. data/ext/carray_operator.c +1171 -364
  108. data/ext/carray_order.c +505 -133
  109. data/ext/carray_partition.c +112 -65
  110. data/ext/carray_random.c +327 -239
  111. data/ext/carray_round.c +273 -0
  112. data/ext/carray_scatter.c +346 -78
  113. data/ext/carray_segment.c +257 -0
  114. data/ext/carray_slab.c +249 -86
  115. data/ext/carray_sort.c +224 -227
  116. data/ext/carray_sort_kernel.c +8 -1
  117. data/ext/carray_struct.c +118 -39
  118. data/ext/carray_test.c +193 -69
  119. data/ext/carray_time_text.c +1182 -0
  120. data/ext/carray_undef.c +4 -0
  121. data/ext/carray_utils.c +579 -113
  122. data/ext/extconf.rb +27 -2
  123. data/ext/mk_call_cfunc.rb +19 -4
  124. data/ext/mk_pow5_table.rb +35 -0
  125. data/ext/mkkernel.rb +1202 -1014
  126. data/ext/ruby_carray.c +17 -5
  127. data/ext/version.h +4 -4
  128. data/ext/version.rb +4 -2
  129. data/lib/carray/attribute.rb +160 -17
  130. data/lib/carray/autoload_carray.rb +23 -27
  131. data/lib/carray/autoload_method_extension.rb +20 -5
  132. data/lib/carray/axis_group.rb +360 -63
  133. data/lib/carray/basics.rb +162 -28
  134. data/lib/carray/bincount_nd.rb +18 -2
  135. data/lib/carray/block_iterator.rb +231 -58
  136. data/lib/carray/boolean_reduce.rb +34 -42
  137. data/lib/carray/categorical.rb +242 -52
  138. data/lib/carray/categorical_iterator.rb +437 -827
  139. data/lib/carray/complex.rb +41 -34
  140. data/lib/carray/conditional.rb +150 -14
  141. data/lib/carray/const_string.rb +59 -4
  142. data/lib/carray/construct.rb +15 -11
  143. data/lib/carray/data_type_extension.rb +1 -0
  144. data/lib/carray/distance_limit.rb +77 -0
  145. data/lib/carray/fixlen_string.rb +7 -1
  146. data/lib/carray/frame/column_verbs.rb +70 -0
  147. data/lib/carray/frame/concat.rb +157 -6
  148. data/lib/carray/frame/convert.rb +82 -7
  149. data/lib/carray/frame/csv_parser.rb +688 -87
  150. data/lib/carray/frame/describe.rb +80 -0
  151. data/lib/carray/frame/frame.rb +369 -45
  152. data/lib/carray/frame/group.rb +631 -90
  153. data/lib/carray/frame/io.rb +506 -79
  154. data/lib/carray/frame/join.rb +411 -62
  155. data/lib/carray/frame/records.rb +116 -19
  156. data/lib/carray/frame/reshape.rb +455 -0
  157. data/lib/carray/frame/sort.rb +30 -18
  158. data/lib/carray/frame/verbs.rb +868 -61
  159. data/lib/carray/frame/windows.rb +117 -0
  160. data/lib/carray/frame.rb +4 -0
  161. data/lib/carray/fuse_source.rb +118 -2
  162. data/lib/carray/fusion.rb +257 -42
  163. data/lib/carray/histogram.rb +6 -1
  164. data/lib/carray/inspect.rb +54 -13
  165. data/lib/carray/iterator.rb +99 -9
  166. data/lib/carray/key_windows.rb +620 -0
  167. data/lib/carray/lazy.rb +216 -193
  168. data/lib/carray/mask_gap_fill.rb +112 -92
  169. data/lib/carray/math.rb +32 -19
  170. data/lib/carray/meld_reduce.rb +52 -21
  171. data/lib/carray/methods/align_addr.rb +8 -4
  172. data/lib/carray/methods/bin.rb +26 -18
  173. data/lib/carray/methods/bincount.rb +18 -2
  174. data/lib/carray/methods/bit_string.rb +15 -4
  175. data/lib/carray/methods/choose.rb +16 -3
  176. data/lib/carray/methods/composition.rb +18 -10
  177. data/lib/carray/methods/factorize.rb +2 -2
  178. data/lib/carray/methods/gather_nd.rb +25 -5
  179. data/lib/carray/methods/insert_block.rb +9 -14
  180. data/lib/carray/methods/is_between.rb +59 -0
  181. data/lib/carray/methods/is_in.rb +140 -10
  182. data/lib/carray/methods/join.rb +2 -7
  183. data/lib/carray/methods/lag.rb +49 -0
  184. data/lib/carray/methods/locate_addr.rb +182 -45
  185. data/lib/carray/methods/mode.rb +18 -1
  186. data/lib/carray/methods/nunique.rb +11 -6
  187. data/lib/carray/methods/repeat.rb +1 -20
  188. data/lib/carray/methods/resize.rb +21 -23
  189. data/lib/carray/methods/snap.rb +34 -12
  190. data/lib/carray/methods/unique.rb +11 -2
  191. data/lib/carray/methods/value_counts.rb +4 -11
  192. data/lib/carray/record_order.rb +208 -0
  193. data/lib/carray/rng.rb +3 -0
  194. data/lib/carray/runtime.rb +65 -17
  195. data/lib/carray/segment_iterator.rb +1221 -0
  196. data/lib/carray/serialize.rb +214 -30
  197. data/lib/carray/slab_iterator.rb +101 -27
  198. data/lib/carray/stack.rb +10 -4
  199. data/lib/carray/string.rb +105 -5
  200. data/lib/carray/string_operation_extension.rb +12 -4
  201. data/lib/carray/struct.rb +137 -58
  202. data/lib/carray/struct_builder.rb +124 -17
  203. data/lib/carray/time.rb +1222 -186
  204. data/lib/carray/window_iterator.rb +242 -81
  205. data/lib/carray.rb +9 -2
  206. data/yard-stubs/ca_obj_array.rb +4 -4
  207. data/yard-stubs/ca_obj_bitarray.rb +7 -0
  208. data/yard-stubs/ca_obj_bitfield.rb +23 -12
  209. data/yard-stubs/ca_obj_fake.rb +1 -1
  210. data/yard-stubs/ca_obj_field.rb +5 -1
  211. data/yard-stubs/ca_obj_grid.rb +21 -10
  212. data/yard-stubs/ca_obj_refer.rb +5 -4
  213. data/yard-stubs/ca_obj_roll.rb +2 -3
  214. data/yard-stubs/ca_obj_shift.rb +5 -1
  215. data/yard-stubs/ca_obj_stride.rb +10 -7
  216. data/yard-stubs/ca_obj_tile.rb +1 -1
  217. data/yard-stubs/ca_obj_transpose.rb +1 -1
  218. data/yard-stubs/ca_obj_window.rb +9 -5
  219. data/yard-stubs/carray_access.rb +11 -5
  220. data/yard-stubs/carray_attribute.rb +0 -5
  221. data/yard-stubs/carray_broadcast.rb +1 -1
  222. data/yard-stubs/carray_cast.rb +88 -43
  223. data/yard-stubs/carray_conversion.rb +15 -2
  224. data/yard-stubs/carray_copy.rb +12 -5
  225. data/yard-stubs/carray_core.rb +3 -3
  226. data/yard-stubs/carray_count.rb +9 -0
  227. data/yard-stubs/carray_element.rb +10 -4
  228. data/yard-stubs/carray_generate.rb +21 -1
  229. data/yard-stubs/carray_lazy.rb +5 -1
  230. data/yard-stubs/carray_loop.rb +4 -1
  231. data/yard-stubs/carray_mask.rb +60 -12
  232. data/yard-stubs/carray_math.rb +52 -14
  233. data/yard-stubs/carray_median_percentile.rb +15 -8
  234. data/yard-stubs/carray_memory_view.rb +40 -23
  235. data/yard-stubs/carray_order.rb +61 -29
  236. data/yard-stubs/carray_random.rb +13 -4
  237. data/yard-stubs/carray_scatter.rb +21 -9
  238. data/yard-stubs/carray_segment.rb +72 -0
  239. data/yard-stubs/carray_slab.rb +10 -2
  240. data/yard-stubs/carray_sort.rb +49 -8
  241. data/yard-stubs/carray_test.rb +15 -3
  242. data/yard-stubs/carray_utils.rb +0 -26
  243. metadata +19 -5
  244. data/ext/ca_for_each_element.h +0 -239
  245. data/ext/carray_kernels_map.c +0 -3467
  246. data/lib/carray/arrow_tensor.rb +0 -401
  247. data/lib/carray/table.rb +0 -108
@@ -12,6 +12,7 @@
12
12
  ---------------------------------------------------------------------------- */
13
13
 
14
14
  #include "carray.h"
15
+ #include "carray_internal.h"
15
16
 
16
17
  typedef struct {
17
18
  int16_t obj_type;
@@ -32,6 +33,8 @@ typedef struct {
32
33
  ca_size_t bit_offset;
33
34
  uint64_t bit_mask;
34
35
  ca_size_t bit_start; /* original offset before endian adjustment */
36
+ ca_size_t bit_length; /* width of the field in bits */
37
+ int8_t sign_extend; /* the field is read as a signed integer */
35
38
  } CABitfield;
36
39
 
37
40
  static size_t
@@ -73,20 +76,6 @@ static int8_t CA_OBJ_BITFIELD;
73
76
 
74
77
  static VALUE rb_cCABitfield;
75
78
 
76
- static ca_size_t
77
- bitfield_bitlen (uint64_t bit_mask, ca_size_t bytes)
78
- {
79
- ca_size_t bitsize = bytes * 8;
80
- ca_size_t count = 0;
81
- ca_size_t i;
82
- for (i=0; i<bitsize; i++) {
83
- if ( ( bit_mask >> i ) & 1 ) {
84
- count++;
85
- }
86
- }
87
- return count;
88
- }
89
-
90
79
  /* Generic per-cell fetch: load up to 8 bytes from src starting at
91
80
  byte_offset, mask with bit_mask, shift down by bit_offset, and
92
81
  write the low `dwrite` bytes of the result to dst.
@@ -100,8 +89,10 @@ static void
100
89
  bitfield_fetch(char *dst, ca_size_t dbytes,
101
90
  char *src, ca_size_t sbytes,
102
91
  ca_size_t byte_offset, ca_size_t bit_offset, uint64_t bit_mask,
92
+ ca_size_t bit_length, int sign_extend,
103
93
  ca_size_t elements)
104
94
  {
95
+ uint64_t sign = ( sign_extend && bit_length < 64 ) ? ( 1ULL << ( bit_length - 1 ) ) : 0;
105
96
  ca_size_t k;
106
97
  ca_size_t span = sbytes - byte_offset;
107
98
  if (span > 8) span = 8;
@@ -110,6 +101,9 @@ bitfield_fetch(char *dst, ca_size_t dbytes,
110
101
  uint64_t tmp = 0;
111
102
  memcpy(&tmp, src + k * sbytes + byte_offset, (size_t) span);
112
103
  uint64_t result = (tmp & bit_mask) >> bit_offset;
104
+ if ( result & sign ) {
105
+ result |= ~( ( sign << 1 ) - 1 ); /* the field's top bit is its sign */
106
+ }
113
107
  memcpy(dst + k * dbytes, &result, (size_t) dwrite);
114
108
  }
115
109
  }
@@ -142,12 +136,14 @@ bitfield_store(char *src, ca_size_t sbytes,
142
136
 
143
137
  /* ------------------------------------------------------------------- */
144
138
 
139
+ /* `data_type` is the integer type the field is read as, or CA_NONE for
140
+ the narrowest unsigned type that holds it (boolean for one bit). A
141
+ signed type reads the field's top bit as its sign. */
145
142
  int
146
143
  ca_bitfield_setup (CABitfield *ca, CArray *parent,
147
- ca_size_t offset, ca_size_t bitlen)
144
+ ca_size_t offset, ca_size_t bitlen, int8_t data_type)
148
145
  {
149
146
  int8_t ndim;
150
- int8_t data_type;
151
147
  ca_size_t bytes = 0, elements;
152
148
  ca_size_t bitsize;
153
149
  ca_size_t byte_offset;
@@ -163,11 +159,37 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
163
159
  rb_raise(rb_eIndexError, "invalid bit length specified for bit field");
164
160
  }
165
161
 
166
- if ( offset + bitlen -1 >= bitsize ) {
162
+ if ( offset < 0 || offset + bitlen -1 >= bitsize ) {
167
163
  rb_raise(rb_eIndexError, "invalid offset for bit field");
168
164
  }
169
165
 
170
- if ( bitlen == 1 ) {
166
+ /* The bits of an object cell are a reference: writing them would leave
167
+ the cell pointing nowhere. A complex cell is refused as bitarray
168
+ refuses it. */
169
+ if ( ca_is_object_type(parent) || ca_is_complex_type(parent) ) {
170
+ rb_raise(rb_eCADataTypeError, "invalid data_type for bitfield");
171
+ }
172
+
173
+ /* A field is read with one 8-byte load from the byte it starts in. */
174
+ if ( offset % 8 + bitlen > 64 ) {
175
+ rb_raise(rb_eIndexError,
176
+ "a bit field of %lld bits at bit %lld spans more than 8 bytes",
177
+ (long long) bitlen, (long long) offset);
178
+ }
179
+
180
+ if ( data_type != CA_NONE ) {
181
+ switch ( data_type ) {
182
+ case CA_BOOLEAN:
183
+ case CA_INT8: case CA_UINT8: case CA_INT16: case CA_UINT16:
184
+ case CA_INT32: case CA_UINT32: case CA_INT64: case CA_UINT64:
185
+ break;
186
+ default:
187
+ rb_raise(rb_eCADataTypeError,
188
+ "a bit field is read as an integer type, not <%s>",
189
+ ca_type_name[data_type]);
190
+ }
191
+ }
192
+ else if ( bitlen == 1 ) {
171
193
  data_type = CA_BOOLEAN;
172
194
  }
173
195
  else if ( bitlen <= 8 ) {
@@ -183,18 +205,20 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
183
205
  data_type = CA_UINT64;
184
206
  }
185
207
 
186
- CA_CHECK_BYTES(data_type, bytes);
187
-
188
- if ( bitlen > bytes * 8 ) {
189
- rb_raise(rb_eArgError, "invalid bit length for specified data_type");
190
- }
208
+ CA_CHECK_BYTES_GIVEN(data_type, bytes);
191
209
 
192
- if ( ( data_type == CA_BOOLEAN ) && ( bitlen > 1 ) ) {
193
- rb_raise(rb_eArgError, "invalid bit length for specified data_type");
210
+ if ( bitlen > bytes * 8 ||
211
+ ( ( data_type == CA_BOOLEAN ) && ( bitlen > 1 ) ) ) {
212
+ rb_raise(rb_eArgError, "a bit field of %lld bits does not fit <%s>",
213
+ (long long) bitlen, ca_type_name[data_type]);
194
214
  }
195
215
 
196
216
  if ( ca_endian == CA_BIG_ENDIAN ) {
197
- byte_offset = parent->bytes - offset/8 - bytes;
217
+ /* The window is placed by the narrowest width that holds the field,
218
+ not by the type it is read as, which may be wider. */
219
+ ca_size_t window = ( bitlen <= 8 ) ? 1 : ( bitlen <= 16 ) ? 2 :
220
+ ( bitlen <= 32 ) ? 4 : 8;
221
+ byte_offset = parent->bytes - offset/8 - window;
198
222
  bit_offset = offset % 8;
199
223
  bit_mask = 0;
200
224
  for (i=0; i<bitlen; i++) {
@@ -217,6 +241,12 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
217
241
  }
218
242
  }
219
243
 
244
+ /* ca == NULL asks for the checks above only, so that a constructor can
245
+ run them before it allocates. */
246
+ if ( ca == NULL ) {
247
+ return 0;
248
+ }
249
+
220
250
  ca->obj_type = CA_OBJ_BITFIELD;
221
251
  ca->data_type = data_type;
222
252
  ca->flags = 0;
@@ -237,21 +267,25 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
237
267
  ca->bit_offset = bit_offset;
238
268
  ca->bit_mask = bit_mask;
239
269
  ca->bit_start = offset; /* preserve original offset for clone/copy */
270
+ ca->bit_length = bitlen;
271
+ ca->sign_extend = ( data_type == CA_INT8 || data_type == CA_INT16 ||
272
+ data_type == CA_INT32 || data_type == CA_INT64 );
240
273
 
241
274
  memcpy(ca->dim, parent->dim, ndim * sizeof(ca_size_t));
242
275
 
243
- if ( ca_has_mask(parent) ) {
244
- ca_create_mask(ca);
245
- }
246
276
 
247
277
  return 0;
248
278
  }
249
279
 
250
280
  CABitfield *
251
- ca_bitfield_new (CArray *parent, ca_size_t offset, ca_size_t bitlen)
281
+ ca_bitfield_new (CArray *parent, ca_size_t offset, ca_size_t bitlen,
282
+ int8_t data_type)
252
283
  {
253
- CABitfield *ca = (CABitfield *) ca_array_alloc(CA_OBJ_BITFIELD, parent->ndim);
254
- ca_bitfield_setup(ca, parent, offset, bitlen);
284
+ CABitfield *ca;
285
+ ca_bitfield_setup(NULL, parent, offset, bitlen, data_type);
286
+ ca = (CABitfield *) ca_array_alloc(CA_OBJ_BITFIELD, parent->ndim);
287
+ ca_bitfield_setup(ca, parent, offset, bitlen, data_type);
288
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
255
289
  return ca;
256
290
  }
257
291
 
@@ -281,9 +315,8 @@ static void *
281
315
  ca_bitfield_func_clone (void *ap)
282
316
  {
283
317
  CABitfield *ca = (CABitfield *) ap;
284
- return ca_bitfield_new(ca->parent,
285
- ca->bit_start,
286
- bitfield_bitlen(ca->bit_mask, ca->bytes));
318
+ return ca_bitfield_new(ca->parent, ca->bit_start, ca->bit_length,
319
+ ca->data_type);
287
320
  }
288
321
 
289
322
  /* Per-cell get/put: fetch the parent cell into a scratch buffer,
@@ -293,19 +326,21 @@ static void
293
326
  ca_bitfield_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
294
327
  {
295
328
  CABitfield *ca = (CABitfield *) ap;
296
- char *v = xmalloc(ca->parent->bytes);
329
+ volatile VALUE holder;
330
+ char *v = ALLOCV_N(char, holder, ca->parent->bytes);
297
331
  ca_fetch_index(ca->parent, idx, v);
298
332
  if ( dir == CA_XFER_GET ) {
299
333
  memset(data, 0, ca->bytes);
300
334
  bitfield_fetch(data, ca->bytes, v, ca->parent->bytes,
301
- ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
335
+ ca->byte_offset, ca->bit_offset, ca->bit_mask,
336
+ ca->bit_length, ca->sign_extend, 1);
302
337
  }
303
338
  else {
304
339
  bitfield_store(data, ca->bytes, v, ca->parent->bytes,
305
340
  ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
306
341
  ca_store_index(ca->parent, idx, v);
307
342
  }
308
- xfree(v);
343
+ ALLOCV_END(holder);
309
344
  }
310
345
 
311
346
  /* Batched gather / scatter. CABitfield is a 1:1 view (each parent
@@ -342,7 +377,8 @@ ca_bitfield_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
342
377
  directly from the attached parent. */
343
378
  memset(d, 0, n * ca->bytes);
344
379
  bitfield_fetch(d, ca->bytes, eff_parent->ptr, pbytes,
345
- ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
380
+ ca->byte_offset, ca->bit_offset, ca->bit_mask,
381
+ ca->bit_length, ca->sign_extend, n);
346
382
  } else {
347
383
  /* Bulk RMW directly against parent memory (bitfield_store
348
384
  preserves non-field bits). */
@@ -359,7 +395,8 @@ ca_bitfield_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
359
395
  for (i = 0; i < n; i++) {
360
396
  memset(d + i * ca->bytes, 0, ca->bytes);
361
397
  bitfield_fetch(d + i * ca->bytes, ca->bytes, v + i * pbytes, pbytes,
362
- ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
398
+ ca->byte_offset, ca->bit_offset, ca->bit_mask,
399
+ ca->bit_length, ca->sign_extend, 1);
363
400
  }
364
401
  }
365
402
  else {
@@ -382,6 +419,7 @@ static void
382
419
  ca_bitfield_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
383
420
  ca_size_t *strides, void *data, int dir)
384
421
  {
422
+ if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
385
423
  CABitfield *ca = (CABitfield *) ap;
386
424
  int8_t ndim = ca->ndim;
387
425
  ca_size_t native[CA_RANK_MAX], idx[CA_RANK_MAX];
@@ -412,7 +450,7 @@ ca_bitfield_func_allocate (void *ap)
412
450
  {
413
451
  CABitfield *ca = (CABitfield *) ap;
414
452
  ca_attach(ca->parent);
415
- ca->ptr = xmalloc(ca_length(ca));
453
+ ca->ptr = ca_alloc_cells((CArray *) ca);
416
454
  }
417
455
 
418
456
  static void
@@ -420,7 +458,7 @@ ca_bitfield_func_attach (void *ap)
420
458
  {
421
459
  CABitfield *ca = (CABitfield *) ap;
422
460
  ca_attach(ca->parent);
423
- ca->ptr = xmalloc(ca_length(ca));
461
+ ca->ptr = ca_alloc_cells((CArray *) ca);
424
462
  ca_bitfield_attach(ca);
425
463
  }
426
464
 
@@ -467,7 +505,8 @@ ca_bitfield_func_xfer_all (void *ap, void *data, int dir)
467
505
  if ( dir == CA_XFER_GET ) {
468
506
  memset(d, 0, n * ca->bytes);
469
507
  bitfield_fetch(d, ca->bytes, eff_parent->ptr, pbytes,
470
- ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
508
+ ca->byte_offset, ca->bit_offset, ca->bit_mask,
509
+ ca->bit_length, ca->sign_extend, n);
471
510
  } else {
472
511
  bitfield_store(d, ca->bytes, eff_parent->ptr, pbytes,
473
512
  ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
@@ -491,7 +530,8 @@ ca_bitfield_func_xfer_all (void *ap, void *data, int dir)
491
530
  ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_GET);
492
531
  memset(d, 0, n * ca->bytes);
493
532
  bitfield_fetch(d, ca->bytes, scratch, pbytes,
494
- ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
533
+ ca->byte_offset, ca->bit_offset, ca->bit_mask,
534
+ ca->bit_length, ca->sign_extend, n);
495
535
  } else {
496
536
  /* CAREFUL: gather parent into scratch before splicing so the
497
537
  non-field bits are preserved across the RMW. */
@@ -510,8 +550,7 @@ ca_bitfield_func_fill_data (void *ap, void *ptr)
510
550
  CABitfield *ca = (CABitfield *) ap;
511
551
  ca_attach(ca->parent);
512
552
  ca_bitfield_fill(ca, ptr);
513
- ca_sync(ca->parent);
514
- ca_detach(ca->parent);
553
+ ca_sync_detach(ca->parent);
515
554
  }
516
555
 
517
556
 
@@ -542,20 +581,6 @@ ca_bitfield_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
542
581
  ca_fill_stride_via_addrs(ap, base, ndim, counts, steps, ptr);
543
582
  }
544
583
 
545
- static void
546
- ca_bitfield_func_create_mask (void *ap)
547
- {
548
- CABitfield *ca = (CABitfield *) ap;
549
-
550
- ca_update_mask(ca->parent);
551
- if ( ! ca->parent->mask ) {
552
- ca_create_mask(ca->parent);
553
- }
554
-
555
- ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
556
- CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
557
- }
558
-
559
584
  ca_operation_function_t ca_bitfield_func = {
560
585
  -1, /* CA_OBJ_BITFIELD */
561
586
  CA_VIEW_ARRAY,
@@ -566,7 +591,7 @@ ca_operation_function_t ca_bitfield_func = {
566
591
  ca_bitfield_func_sync,
567
592
  ca_bitfield_func_detach,
568
593
  ca_bitfield_func_fill_data,
569
- ca_bitfield_func_create_mask,
594
+ ca_view_func_create_mask,
570
595
  ca_bitfield_func_xfer_index,
571
596
  ca_bitfield_func_xfer_addrs,
572
597
  NULL, /* fold_stride: never fold — per-cell bit transform */
@@ -583,7 +608,8 @@ ca_bitfield_attach (CABitfield *ca)
583
608
  {
584
609
  memset(ca->ptr, 0, ca_length(ca));
585
610
  bitfield_fetch(ca->ptr, ca->bytes, ca->parent->ptr, ca->parent->bytes,
586
- ca->byte_offset, ca->bit_offset, ca->bit_mask, ca->elements);
611
+ ca->byte_offset, ca->bit_offset, ca->bit_mask,
612
+ ca->bit_length, ca->sign_extend, ca->elements);
587
613
  }
588
614
 
589
615
  static void
@@ -614,14 +640,15 @@ ca_bitfield_fill (CABitfield *ca, char *ptr)
614
640
  /* ------------------------------------------------------------------- */
615
641
 
616
642
  VALUE
617
- rb_ca_bitfield_new (VALUE cary, ca_size_t offset, ca_size_t bitlen)
643
+ rb_ca_bitfield_new (VALUE cary, ca_size_t offset, ca_size_t bitlen,
644
+ int8_t data_type)
618
645
  {
619
646
  volatile VALUE obj;
620
647
  CArray *parent;
621
648
  CABitfield *ca;
622
649
  rb_check_carray_object(cary);
623
650
  TypedData_Get_Struct(cary, CArray, &carray_data_type, parent);
624
- ca = ca_bitfield_new(parent, offset, bitlen);
651
+ ca = ca_bitfield_new(parent, offset, bitlen, data_type);
625
652
  obj = ca_wrap_struct(ca);
626
653
  rb_ca_set_parent(obj, cary);
627
654
  return obj;
@@ -641,6 +668,9 @@ rb_ca_bitfield (int argc, VALUE *argv, VALUE self)
641
668
 
642
669
  if ( TYPE(rrange) == T_FIXNUM ) {
643
670
  offset = NUM2INT(rrange);
671
+ if ( offset < 0 ) {
672
+ offset += ca->bytes * 8;
673
+ }
644
674
  bitlen = 1;
645
675
  }
646
676
  else {
@@ -651,7 +681,8 @@ rb_ca_bitfield (int argc, VALUE *argv, VALUE self)
651
681
  }
652
682
  }
653
683
 
654
- return rb_ca_bitfield_new(self, offset, bitlen);
684
+ return rb_ca_bitfield_new(self, offset, bitlen,
685
+ NIL_P(rtype) ? CA_NONE : rb_ca_guess_type(rtype));
655
686
  }
656
687
 
657
688
  static VALUE
@@ -667,14 +698,15 @@ rb_ca_bitfield_initialize_copy (VALUE self, VALUE other)
667
698
  CABitfield *ca, *cs;
668
699
 
669
700
  TypedData_Get_Struct(self, CABitfield, &cabitfield_data_type, ca);
701
+ ca_check_uninitialized(ca);
670
702
  TypedData_Get_Struct(other, CABitfield, &cabitfield_data_type, cs);
671
703
 
672
704
  if ( ca_func[CA_OBJ_BITFIELD].pool_init ) {
673
705
  ca_array_pool_alloc(ca, CA_OBJ_BITFIELD, cs->parent->ndim);
674
706
  }
675
- ca_bitfield_setup(ca, cs->parent,
676
- cs->bit_start,
677
- bitfield_bitlen(cs->bit_mask, cs->bytes));
707
+ ca_bitfield_setup(ca, cs->parent, cs->bit_start, cs->bit_length,
708
+ cs->data_type);
709
+ ca_view_inherit_mask((VALUE) ca);
678
710
 
679
711
  return self;
680
712
  }
data/ext/ca_obj_block.c CHANGED
@@ -124,6 +124,12 @@ ca_block_setup (CABlock *ca, CArray *parent, int8_t ndim, ca_size_t *dim,
124
124
  }
125
125
  }
126
126
 
127
+ /* ca == NULL asks for the checks above only, so that a constructor can
128
+ run them before it allocates. */
129
+ if ( ca == NULL ) {
130
+ return 0;
131
+ }
132
+
127
133
  /* strides[k] = step[k] * Pi_{j>k} size0[j] * parent->bytes */
128
134
  suffix = parent->bytes;
129
135
  for (i = ndim - 1; i >= 0; i--) {
@@ -141,10 +147,9 @@ ca_block_setup (CABlock *ca, CArray *parent, int8_t ndim, ca_size_t *dim,
141
147
  }
142
148
  }
143
149
 
144
- /* CAREFUL: the CABlock tail (offset / start / step / count / size0)
145
- must be filled BEFORE ca_stride_setup. ca_stride_setup may auto-
146
- dispatch ca_create_mask when the parent has a mask, and
147
- ca_block_func_create_mask reads those tail fields.
150
+ /* The CABlock tail (offset / start / step / count / size0) is filled
151
+ here; ca_block_func_create_mask reads it when the constructor takes
152
+ the parent's mask (ca_view_inherit_mask) after this setup.
148
153
 
149
154
  Pool path: start/step/count/size0 already point into _pool (wired
150
155
  by ca_block_pool_init); only memcpy the values. Non-pool path:
@@ -161,10 +166,10 @@ ca_block_setup (CABlock *ca, CArray *parent, int8_t ndim, ca_size_t *dim,
161
166
  memcpy(ca->count, count, ndim * sizeof(ca_size_t));
162
167
  memcpy(ca->size0, dim, ndim * sizeof(ca_size_t));
163
168
 
164
- ca_stride_setup((CAStride *) ca, CA_OBJ_BLOCK, parent,
165
- parent->data_type, parent->bytes,
166
- ndim, count, strides,
167
- base_offset_elements * parent->bytes);
169
+ ca_stride_setup_view((CAStride *) ca, CA_OBJ_BLOCK, parent,
170
+ parent->data_type, parent->bytes,
171
+ ndim, count, strides,
172
+ base_offset_elements * parent->bytes);
168
173
 
169
174
  return 0;
170
175
  }
@@ -174,8 +179,11 @@ ca_block_new (CArray *parent, int8_t ndim, ca_size_t *dim,
174
179
  ca_size_t *start, ca_size_t *step, ca_size_t *count,
175
180
  ca_size_t offset)
176
181
  {
177
- CABlock *ca = (CABlock *) ca_array_alloc(CA_OBJ_BLOCK, ndim);
182
+ CABlock *ca;
183
+ ca_block_setup(NULL, parent, ndim, dim, start, step, count, offset);
184
+ ca = (CABlock *) ca_array_alloc(CA_OBJ_BLOCK, ndim);
178
185
  ca_block_setup(ca, parent, ndim, dim, start, step, count, offset);
186
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
179
187
  return ca;
180
188
  }
181
189
 
@@ -254,6 +262,7 @@ rb_cb_initialize_copy (VALUE self, VALUE other)
254
262
  {
255
263
  CABlock *ca, *cs;
256
264
  TypedData_Get_Struct(self, CABlock, &cablock_data_type, ca);
265
+ ca_check_uninitialized(ca);
257
266
  TypedData_Get_Struct(other, CABlock, &cablock_data_type, cs);
258
267
  /* `self` was created by rb_cb_s_allocate (TypedData_Make_Struct) with
259
268
  ca->_pool == NULL. Wire up the pool before ca_block_setup so the
@@ -264,6 +273,7 @@ rb_cb_initialize_copy (VALUE self, VALUE other)
264
273
  }
265
274
  ca_block_setup(ca, cs->parent, cs->ndim, cs->size0,
266
275
  cs->start, cs->step, cs->count, cs->offset);
276
+ ca_view_inherit_mask((VALUE) ca);
267
277
  rb_ca_set_parent(self, rb_ca_parent(other));
268
278
  return self;
269
279
  }
@@ -13,6 +13,7 @@
13
13
  ---------------------------------------------------------------------------- */
14
14
 
15
15
  #include "carray.h"
16
+ #include "carray_internal.h"
16
17
  #include "ca_iter_substrate.h" /* ca_xfer_stride_transform_fused */
17
18
  #include "ca_monop_dispatch.h" /* CA_MONOP_BYTE_SWAP dispatch id */
18
19
  #include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE for CARecord parent */
@@ -192,12 +193,18 @@ VALUE rb_cCAByteSwap;
192
193
  int
193
194
  ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
194
195
  {
195
- CA_CHECK_DATA_TYPE(parent->data_type);
196
+ CA_CHECK_DATA_TYPE_GIVEN(parent->data_type);
196
197
 
197
198
  if ( parent->data_type == CA_OBJECT ) {
198
199
  rb_raise(rb_eCADataTypeError, "object array can't be byte-swapped");
199
200
  }
200
201
 
202
+ /* ca == NULL asks for the checks above only, so that a constructor can
203
+ run them before it allocates. */
204
+ if ( ca == NULL ) {
205
+ return 0;
206
+ }
207
+
201
208
  ca->obj_type = CA_OBJ_BYTE_SWAP;
202
209
  ca->data_type = parent->data_type;
203
210
  ca->flags = 0;
@@ -216,9 +223,6 @@ ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
216
223
  ca->nosync = 0;
217
224
  ca->data_class = data_class; /* Qnil if parent has no data_class */
218
225
 
219
- if ( ca_has_mask(parent) ) {
220
- ca_create_mask(ca);
221
- }
222
226
  if ( ca_is_scalar(parent) ) {
223
227
  ca_set_flag(ca, CA_FLAG_SCALAR);
224
228
  }
@@ -229,8 +233,11 @@ ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
229
233
  CAByteSwap *
230
234
  ca_byte_swap_new (CArray *parent, VALUE data_class)
231
235
  {
232
- CAByteSwap *ca = (CAByteSwap *) ca_array_alloc(CA_OBJ_BYTE_SWAP, parent->ndim);
236
+ CAByteSwap *ca;
237
+ ca_byte_swap_setup(NULL, parent, data_class);
238
+ ca = (CAByteSwap *) ca_array_alloc(CA_OBJ_BYTE_SWAP, parent->ndim);
233
239
  ca_byte_swap_setup(ca, parent, data_class);
240
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
234
241
  return ca;
235
242
  }
236
243
 
@@ -319,12 +326,12 @@ ca_byte_swap_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
319
326
  ca_byte_swap_apply_one(ca, (char *) data);
320
327
  }
321
328
  else {
322
- char v[32];
323
- char *buf = (ca->bytes <= 32) ? v : xmalloc(ca->bytes);
329
+ volatile VALUE holder;
330
+ char *buf = ALLOCV_N(char, holder, ca->bytes);
324
331
  memcpy(buf, data, ca->bytes);
325
332
  ca_byte_swap_apply_one(ca, buf);
326
333
  ca_store_index(ca->parent, idx, buf);
327
- if ( buf != v ) xfree(buf);
334
+ ALLOCV_END(holder);
328
335
  }
329
336
  }
330
337
 
@@ -405,6 +412,7 @@ static void
405
412
  ca_byte_swap_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
406
413
  ca_size_t *strides, void *data, int dir)
407
414
  {
415
+ if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
408
416
  CAByteSwap *ca = (CAByteSwap *) ap;
409
417
  char *d = (char *) data;
410
418
  int is_struct = ( ca->data_type == CA_FIXLEN && RTEST(ca->data_class) );
@@ -454,7 +462,7 @@ ca_byte_swap_func_allocate (void *ap)
454
462
  {
455
463
  CAByteSwap *ca = (CAByteSwap *) ap;
456
464
  ca_attach(ca->parent);
457
- ca->ptr = xmalloc(ca_length(ca));
465
+ ca->ptr = ca_alloc_cells((CArray *) ca);
458
466
  }
459
467
 
460
468
  static void
@@ -462,7 +470,7 @@ ca_byte_swap_func_attach (void *ap)
462
470
  {
463
471
  CAByteSwap *ca = (CAByteSwap *) ap;
464
472
  ca_attach(ca->parent);
465
- ca->ptr = xmalloc(ca_length(ca));
473
+ ca->ptr = ca_alloc_cells((CArray *) ca);
466
474
  memcpy(ca->ptr, ca->parent->ptr, ca_length(ca));
467
475
  ca_byte_swap_apply(ca, ca->ptr);
468
476
  }
@@ -471,10 +479,17 @@ static void
471
479
  ca_byte_swap_func_sync (void *ap)
472
480
  {
473
481
  CAByteSwap *ca = (CAByteSwap *) ap;
474
- /* Swap is involutive, so applying it once to the view buffer
475
- restores the parent byte order before the copy-back. */
476
- ca_byte_swap_apply(ca, ca->ptr);
477
- memcpy(ca->parent->ptr, ca->ptr, ca_length(ca));
482
+ /* Swap is involutive, so applying it once to a copy of the view buffer
483
+ restores the parent byte order. Not the view buffer in place: the
484
+ window stays open after a sync, and a second sync (a stack holding
485
+ this view twice) would swap it again. The swap of a record calls
486
+ Ruby, so it runs on the copy and reaches the parent only whole. */
487
+ volatile VALUE holder;
488
+ char *tmp = ALLOCV_N(char, holder, ca_length(ca));
489
+ memcpy(tmp, ca->ptr, ca_length(ca));
490
+ ca_byte_swap_apply(ca, tmp);
491
+ memcpy(ca->parent->ptr, tmp, ca_length(ca));
492
+ ALLOCV_END(holder);
478
493
  ca_sync(ca->parent);
479
494
  }
480
495
 
@@ -509,8 +524,8 @@ static void
509
524
  ca_byte_swap_func_fill_data (void *ap, void *ptr)
510
525
  {
511
526
  CAByteSwap *ca = (CAByteSwap *) ap;
512
- char v[32];
513
- char *buf = (ca->bytes <= 32) ? v : xmalloc(ca->bytes);
527
+ volatile VALUE holder;
528
+ char *buf = ALLOCV_N(char, holder, ca->bytes);
514
529
  memcpy(buf, ptr, ca->bytes);
515
530
  if ( !ca_byte_swap_apply_one(ca, buf) ) {
516
531
  /* Bare CA_FIXLEN fill: broadcast the raw bytes into the view
@@ -523,13 +538,12 @@ ca_byte_swap_func_fill_data (void *ap, void *ptr)
523
538
  memcpy(ca->ptr + i * ca->bytes, ptr, ca->bytes);
524
539
  }
525
540
  }
526
- ca_sync(ca);
527
- ca_detach(ca);
528
- if ( buf != v ) xfree(buf);
541
+ ca_sync_detach(ca);
542
+ ALLOCV_END(holder);
529
543
  return;
530
544
  }
531
545
  ca_fill(ca->parent, buf);
532
- if ( buf != v ) xfree(buf);
546
+ ALLOCV_END(holder);
533
547
  }
534
548
 
535
549
  /* fill_data with a region. Swapping is per value, not per cell, so the one
@@ -543,8 +557,8 @@ ca_byte_swap_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
543
557
  ca_size_t *counts, ca_size_t *steps, void *ptr)
544
558
  {
545
559
  CAByteSwap *ca = (CAByteSwap *) ap;
546
- char v[32];
547
- char *buf = (ca->bytes <= 32) ? v : xmalloc(ca->bytes);
560
+ volatile VALUE holder;
561
+ char *buf = ALLOCV_N(char, holder, ca->bytes);
548
562
  memcpy(buf, ptr, ca->bytes);
549
563
  if ( ca_byte_swap_apply_one(ca, buf) ) {
550
564
  ca_fill_stride(ca->parent, base, ndim, counts, steps, buf);
@@ -552,7 +566,7 @@ ca_byte_swap_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
552
566
  else {
553
567
  ca_fill_stride_default(ca, base, ndim, counts, steps, ptr);
554
568
  }
555
- if ( buf != v ) xfree(buf);
569
+ ALLOCV_END(holder);
556
570
  }
557
571
 
558
572
  static void
@@ -560,8 +574,8 @@ ca_byte_swap_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
560
574
  void *ptr)
561
575
  {
562
576
  CAByteSwap *ca = (CAByteSwap *) ap;
563
- char v[32];
564
- char *buf = (ca->bytes <= 32) ? v : xmalloc(ca->bytes);
577
+ volatile VALUE holder;
578
+ char *buf = ALLOCV_N(char, holder, ca->bytes);
565
579
  memcpy(buf, ptr, ca->bytes);
566
580
  if ( ca_byte_swap_apply_one(ca, buf) ) {
567
581
  ca_fill_addrs(ca->parent, n, addrs, buf);
@@ -569,23 +583,7 @@ ca_byte_swap_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
569
583
  else {
570
584
  ca_fill_addrs_default(ca, n, addrs, ptr);
571
585
  }
572
- if ( buf != v ) xfree(buf);
573
- }
574
-
575
- static void
576
- ca_byte_swap_func_create_mask (void *ap)
577
- {
578
- CAByteSwap *ca = (CAByteSwap *) ap;
579
- ca_update_mask(ca->parent);
580
- if ( ! ca->parent->mask ) {
581
- ca_create_mask(ca->parent);
582
- }
583
- /* Mask is byte-wide (boolean), so the swap is a no-op for the
584
- mask itself. Share the parent's mask via a CARefer to keep the
585
- two in lockstep. */
586
- ca->mask =
587
- (CArray *) ca_refer_new(ca->parent->mask,
588
- CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
586
+ ALLOCV_END(holder);
589
587
  }
590
588
 
591
589
  ca_operation_function_t ca_byte_swap_func = {
@@ -598,7 +596,7 @@ ca_operation_function_t ca_byte_swap_func = {
598
596
  ca_byte_swap_func_sync,
599
597
  ca_byte_swap_func_detach,
600
598
  ca_byte_swap_func_fill_data,
601
- ca_byte_swap_func_create_mask,
599
+ ca_view_func_create_mask,
602
600
  ca_byte_swap_func_xfer_index,
603
601
  ca_byte_swap_func_xfer_addrs,
604
602
  NULL, /* fold_stride: never fold — value-conversion boundary */
@@ -658,11 +656,13 @@ rb_ca_byte_swap_initialize_copy (VALUE self, VALUE other)
658
656
  {
659
657
  CAByteSwap *ca, *cs;
660
658
  TypedData_Get_Struct(self, CAByteSwap, &cabyteswap_data_type, ca);
659
+ ca_check_uninitialized(ca);
661
660
  TypedData_Get_Struct(other, CAByteSwap, &cabyteswap_data_type, cs);
662
661
  if ( ca_func[CA_OBJ_BYTE_SWAP].pool_init ) {
663
662
  ca_array_pool_alloc(ca, CA_OBJ_BYTE_SWAP, cs->parent->ndim);
664
663
  }
665
664
  ca_byte_swap_setup(ca, cs->parent, cs->data_class);
665
+ ca_view_inherit_mask((VALUE) ca);
666
666
  return self;
667
667
  }
668
668
 
@@ -732,10 +732,9 @@ rb_ca_swap_bytes_bang (VALUE self)
732
732
  }
733
733
 
734
734
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
735
- ca_attach(ca);
735
+ ca_attach(ca); /* window: nothing raises inside */
736
736
  ca_byte_swap_buffer(ca->data_type, ca->bytes, ca->elements, ca->ptr);
737
- ca_sync(ca);
738
- ca_detach(ca);
737
+ ca_sync_detach(ca);
739
738
  return self;
740
739
  }
741
740